diff options
Diffstat (limited to 'js/src/tests/ecma_5/Function')
-rw-r--r-- | js/src/tests/ecma_5/Function/10.2.1.1.6.js | 35 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/15.3.4.3-01.js | 245 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/Function-arguments-gc.js | 40 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/Function-with-eval.js | 25 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/arguments-caller-callee.js | 66 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/arguments-property-attributes.js | 102 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/browser.js | 0 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/builtin-no-construct.js | 52 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/builtin-no-prototype.js | 40 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/function-bind.js | 288 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/function-call.js | 134 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/function-caller.js | 45 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/redefine-arguments-length.js | 65 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/shell.js | 0 | ||||
-rw-r--r-- | js/src/tests/ecma_5/Function/strict-arguments.js | 453 |
15 files changed, 1590 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/Function/10.2.1.1.6.js b/js/src/tests/ecma_5/Function/10.2.1.1.6.js new file mode 100644 index 000000000..69613386c --- /dev/null +++ b/js/src/tests/ecma_5/Function/10.2.1.1.6.js @@ -0,0 +1,35 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function strictThis() { 'use strict'; return this; } + +/* Check that calls of flat closure slots get the right |this|. */ +function flat(g) { + function h() { return g(); } + return h; +} +assertEq(flat(strictThis)(), undefined); + +/* Check that calls up upvars get the right |this|. */ +function upvar(f) { + function h() { + return f(); + } + return h(); +} +assertEq(upvar(strictThis), undefined); + +/* Check that calls to with-object properties get an appropriate 'this'. */ +var obj = { f: strictThis }; +with (obj) { + /* + * The method won't compile anything containing a 'with', but it can + * compile 'g'. + */ + function g() { return f(); } + assertEq(g(), obj); +} + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/Function/15.3.4.3-01.js b/js/src/tests/ecma_5/Function/15.3.4.3-01.js new file mode 100644 index 000000000..955d77376 --- /dev/null +++ b/js/src/tests/ecma_5/Function/15.3.4.3-01.js @@ -0,0 +1,245 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 562448; +var summary = 'Function.prototype.apply should accept any arraylike arguments'; +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectTypeError(fun, msg) +{ + try + { + fun(); + assertEq(true, false, "should have thrown a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, msg + "; instead threw " + e); + } +} + +function fun() { } + +var global = this; + + +/* Step 1. */ +var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}]; +for (var i = 0, sz = nonfuns.length; i < sz; i++) +{ + var f = function() + { + Function.prototype.apply.apply(nonfuns[i], [1, 2, 3]); + }; + var msg = + "expected TypeError calling Function.prototype.apply with uncallable this"; + expectTypeError(f, msg); +} + + +/* Step 2. */ +var thisObj = {}; + +var currentThis, currentThisBox; +function funLength() +{ + assertEq(arguments.length, 0, "should have been called with no arguments"); + assertEq(this, currentThis, "wrong this"); +} +function strictFunLength() +{ + "use strict"; + assertEq(arguments.length, 0, "should have been called with no arguments"); + assertEq(this, currentThis, "wrong this"); +} + +currentThis = global; +funLength.apply(); +funLength.apply(undefined); +funLength.apply(undefined, undefined); +funLength.apply(undefined, null); + +currentThis = undefined; +strictFunLength.apply(); +strictFunLength.apply(undefined); +strictFunLength.apply(undefined, undefined); +strictFunLength.apply(undefined, null); + +currentThis = null; +strictFunLength.apply(null); +strictFunLength.apply(null, undefined); +strictFunLength.apply(null, null); + +currentThis = thisObj; +funLength.apply(thisObj); +funLength.apply(thisObj, null); +funLength.apply(thisObj, undefined); +strictFunLength.apply(thisObj); +strictFunLength.apply(thisObj, null); +strictFunLength.apply(thisObj, undefined); + +currentThis = 17; +strictFunLength.apply(17); +strictFunLength.apply(17, null); +strictFunLength.apply(17, undefined); + +function funThisPrimitive() +{ + assertEq(arguments.length, 0, "should have been called with no arguments"); + assertEq(this instanceof currentThisBox, true, + "this not instanceof " + currentThisBox); + assertEq(this.valueOf(), currentThis, + "wrong this valueOf()"); +} + +currentThis = 17; +currentThisBox = Number; +funThisPrimitive.apply(17); +funThisPrimitive.apply(17, undefined); +funThisPrimitive.apply(17, null); + +currentThis = "foopy"; +currentThisBox = String; +funThisPrimitive.apply("foopy"); +funThisPrimitive.apply("foopy", undefined); +funThisPrimitive.apply("foopy", null); + +currentThis = false; +currentThisBox = Boolean; +funThisPrimitive.apply(false); +funThisPrimitive.apply(false, undefined); +funThisPrimitive.apply(false, null); + + +/* Step 3. */ +var nonobjs = [1, -1, 2.5, "[[Call]]", true, false]; +for (var i = 0, sz = nonobjs.length; i < sz; i++) +{ + var f = function() { fun.apply(thisObj, nonobjs[i]); }; + var msg = "should have thrown a TypeError with non-object arguments"; + expectTypeError(f, msg); +} + + +/* Step 4. */ +var args = { get length() { throw 42; } }; +try +{ + fun.apply(thisObj, args); +} +catch (e) +{ + assertEq(e, 42, "didn't throw result of [[Get]] on arguments object"); +} + + +/* + * NB: There was an erratum removing the steps numbered 5 and 7 in the original + * version of ES5; see also the comments in js_fun_apply. + */ + +/* Step 5. */ +var called = false; +var argsObjectLength = + { length: { valueOf: function() { called = true; return 17; } } }; + +fun.apply({}, argsObjectLength); +assertEq(called, true, "should have been set in valueOf called via ToUint32"); + +var upvar = "unset"; +var argsObjectPrimitiveLength = + { + length: + { + valueOf: function() { upvar = "valueOf"; return {}; }, + toString: function() + { + upvar = upvar === "valueOf" ? "both" : "toString"; + return 17; + } + } + }; +fun.apply({}, argsObjectPrimitiveLength); +assertEq(upvar, "both", "didn't call all hooks properly"); + + +/* Step 6-9. */ +var seenThis, res, steps; +var argsAccessors = + { + length: 4, + get 0() { steps.push("0"); return 1; }, + get 1() { steps.push("1"); return 2; }, + // make sure values shine through holes + get 3() { steps.push("3"); return 8; }, + }; + +Object.prototype[2] = 729; + +seenThis = "not seen"; +function argsAsArray() +{ + seenThis = this; + steps.push(Math.PI); + return Array.prototype.map.call(arguments, function(v) { return v; }); +} + +steps = []; +res = argsAsArray.apply(thisObj, argsAccessors); +assertEq(seenThis, thisObj, "saw wrong this"); + +assertEq(steps.length, 4, "wrong steps: " + steps); +assertEq(steps[0], "0", "bad step 0"); +assertEq(steps[1], "1", "bad step 1"); +assertEq(steps[2], "3", "bad step 3"); +assertEq(steps[3], Math.PI, "bad last step"); + +assertEq(res.length, 4, "wrong return: " + res); +assertEq(res[0], 1, "wrong ret[0]"); +assertEq(res[1], 2, "wrong ret[0]"); +assertEq(res[2], 729, "wrong ret[0]"); +assertEq(res[3], 8, "wrong ret[0]"); + +seenThis = "not seen"; +function strictArgsAsArray() +{ + "use strict"; + seenThis = this; + steps.push(NaN); + return Array.prototype.map.call(arguments, function(v) { return v; }); +} + +steps = []; +res = strictArgsAsArray.apply(null, argsAccessors); +assertEq(seenThis, null, "saw wrong this"); + +assertEq(steps.length, 4, "wrong steps: " + steps); +assertEq(steps[0], "0", "bad step 0"); +assertEq(steps[1], "1", "bad step 1"); +assertEq(steps[2], "3", "bad step 3"); +assertEq(steps[3], 0 / 0, "bad last step"); + +assertEq(res.length, 4, "wrong return: " + res); +assertEq(res[0], 1, "wrong ret[0]"); +assertEq(res[1], 2, "wrong ret[0]"); +assertEq(res[2], 729, "wrong ret[0]"); +assertEq(res[3], 8, "wrong ret[0]"); + +strictArgsAsArray.apply(17, argsAccessors); +assertEq(seenThis, 17, "saw wrong this"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/Function-arguments-gc.js b/js/src/tests/ecma_5/Function/Function-arguments-gc.js new file mode 100644 index 000000000..250452336 --- /dev/null +++ b/js/src/tests/ecma_5/Function/Function-arguments-gc.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(Android) +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Christian Holler <decoder@own-hero.net> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 623301; +var summary = "Properly root argument names during Function()"; +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +if (typeof gczeal === "function") + gczeal(2); + +function crashMe(n) +{ + var nasty = []; + while (n--) + nasty.push("a" + n); + return Function.apply(null, nasty); +} + +var count = 64; // exact value not important +assertEq(crashMe(count + 1).length, count); + +if (typeof gczeal === "function") + gczeal(0); // reset + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/Function-with-eval.js b/js/src/tests/ecma_5/Function/Function-with-eval.js new file mode 100644 index 000000000..981abf2d0 --- /dev/null +++ b/js/src/tests/ecma_5/Function/Function-with-eval.js @@ -0,0 +1,25 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(new Function( + "eval('var foo = 915805');" + + "return foo;" + )(), + 915805); + +assertEq(new Function( + "eval('function foo() {" + + "return 915805;" + + "}');" + + "return foo;" + )()(), + 915805); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Function/arguments-caller-callee.js b/js/src/tests/ecma_5/Function/arguments-caller-callee.js new file mode 100644 index 000000000..3eda27b49 --- /dev/null +++ b/js/src/tests/ecma_5/Function/arguments-caller-callee.js @@ -0,0 +1,66 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'arguments-caller-callee.js'; +var BUGNUMBER = 514563; +var summary = "arguments.caller and arguments.callee are poison pills in ES5"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// behavior + +function expectTypeError(fun) +{ + try + { + fun(); + throw new Error("didn't throw"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "expected TypeError calling function" + + ("name" in fun ? " " + fun.name : "") + ", instead got: " + e); + } +} + +function bar() { "use strict"; return arguments; } +expectTypeError(function barCaller() { bar().caller; }); +expectTypeError(function barCallee() { bar().callee; }); + +function baz() { return arguments; } +assertEq(baz().callee, baz); + + +// accessor identity + +function strictMode() { "use strict"; return arguments; } +var canonicalTTE = Object.getOwnPropertyDescriptor(strictMode(), "caller").get; + +var args = strictMode(); + +var argsCaller = Object.getOwnPropertyDescriptor(args, "caller"); +assertEq("get" in argsCaller, true); +assertEq("set" in argsCaller, true); +assertEq(argsCaller.get, canonicalTTE); +assertEq(argsCaller.set, canonicalTTE); + +var argsCallee = Object.getOwnPropertyDescriptor(args, "callee"); +assertEq("get" in argsCallee, true); +assertEq("set" in argsCallee, true); +assertEq(argsCallee.get, canonicalTTE); +assertEq(argsCallee.set, canonicalTTE); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/arguments-property-attributes.js b/js/src/tests/ecma_5/Function/arguments-property-attributes.js new file mode 100644 index 000000000..994b97ca4 --- /dev/null +++ b/js/src/tests/ecma_5/Function/arguments-property-attributes.js @@ -0,0 +1,102 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'arguments-property-attributes.js'; +var BUGNUMBER = 516255; +var summary = "Attributes for properties of arguments objects"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// normal + +function args() { return arguments; } +var a = args(0, 1); + +var argProps = Object.getOwnPropertyNames(a).sort(); +assertEq(argProps.indexOf("callee") >= 0, true); +assertEq(argProps.indexOf("0") >= 0, true); +assertEq(argProps.indexOf("1") >= 0, true); +assertEq(argProps.indexOf("length") >= 0, true); + +var calleeDesc = Object.getOwnPropertyDescriptor(a, "callee"); +assertEq(calleeDesc.value, args); +assertEq(calleeDesc.writable, true); +assertEq(calleeDesc.enumerable, false); +assertEq(calleeDesc.configurable, true); + +var zeroDesc = Object.getOwnPropertyDescriptor(a, "0"); +assertEq(zeroDesc.value, 0); +assertEq(zeroDesc.writable, true); +assertEq(zeroDesc.enumerable, true); +assertEq(zeroDesc.configurable, true); + +var oneDesc = Object.getOwnPropertyDescriptor(a, "1"); +assertEq(oneDesc.value, 1); +assertEq(oneDesc.writable, true); +assertEq(oneDesc.enumerable, true); +assertEq(oneDesc.configurable, true); + +var lengthDesc = Object.getOwnPropertyDescriptor(a, "length"); +assertEq(lengthDesc.value, 2); +assertEq(lengthDesc.writable, true); +assertEq(lengthDesc.enumerable, false); +assertEq(lengthDesc.configurable, true); + + +// strict + +function strictArgs() { "use strict"; return arguments; } +var sa = strictArgs(0, 1); + +var strictArgProps = Object.getOwnPropertyNames(sa).sort(); +assertEq(strictArgProps.indexOf("callee") >= 0, true); +assertEq(strictArgProps.indexOf("caller") >= 0, true); +assertEq(strictArgProps.indexOf("0") >= 0, true); +assertEq(strictArgProps.indexOf("1") >= 0, true); +assertEq(strictArgProps.indexOf("length") >= 0, true); + +var strictCalleeDesc = Object.getOwnPropertyDescriptor(sa, "callee"); +assertEq(typeof strictCalleeDesc.get, "function"); +assertEq(typeof strictCalleeDesc.set, "function"); +assertEq(strictCalleeDesc.get, strictCalleeDesc.set); +assertEq(strictCalleeDesc.enumerable, false); +assertEq(strictCalleeDesc.configurable, false); + +var strictCallerDesc = Object.getOwnPropertyDescriptor(sa, "caller"); +assertEq(typeof strictCallerDesc.get, "function"); +assertEq(typeof strictCallerDesc.set, "function"); +assertEq(strictCallerDesc.get, strictCallerDesc.set); +assertEq(strictCallerDesc.enumerable, false); +assertEq(strictCallerDesc.configurable, false); + +var strictZeroDesc = Object.getOwnPropertyDescriptor(sa, "0"); +assertEq(strictZeroDesc.value, 0); +assertEq(strictZeroDesc.writable, true); +assertEq(strictZeroDesc.enumerable, true); +assertEq(strictZeroDesc.configurable, true); + +var strictOneDesc = Object.getOwnPropertyDescriptor(sa, "1"); +assertEq(strictOneDesc.value, 1); +assertEq(strictOneDesc.writable, true); +assertEq(strictOneDesc.enumerable, true); +assertEq(strictOneDesc.configurable, true); + +var strictLengthDesc = Object.getOwnPropertyDescriptor(sa, "length"); +assertEq(strictLengthDesc.value, 2); +assertEq(strictLengthDesc.writable, true); +assertEq(strictLengthDesc.enumerable, false); +assertEq(strictLengthDesc.configurable, true); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/browser.js b/js/src/tests/ecma_5/Function/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/Function/browser.js diff --git a/js/src/tests/ecma_5/Function/builtin-no-construct.js b/js/src/tests/ecma_5/Function/builtin-no-construct.js new file mode 100644 index 000000000..b41ae56f1 --- /dev/null +++ b/js/src/tests/ecma_5/Function/builtin-no-construct.js @@ -0,0 +1,52 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function checkMethod(method) { + try { + new method(); + assertEq(0, 1, "not reached " + method); + } catch (e) { + assertEq(e.message.indexOf(" is not a constructor") === -1, false); + } +} + +function checkMethods(proto) { + var names = Object.getOwnPropertyNames(proto); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + if (["constructor", "arguments", "caller"].indexOf(name) >= 0) + continue; + var prop = proto[name]; + if (typeof prop === "function") + checkMethod(prop); + } +} + +checkMethod(Function.prototype); +checkMethods(JSON); +checkMethods(Math); +checkMethods(Proxy); + +var builtin_ctors = [ + Object, Function, Array, String, Boolean, Number, Date, RegExp, Error, + EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, +]; + +for (var i = 0; i < builtin_ctors.length; i++) { + checkMethods(builtin_ctors[i]); + checkMethods(builtin_ctors[i].prototype); +} + +var builtin_funcs = [ + eval, isFinite, isNaN, parseFloat, parseInt, + decodeURI, decodeURIComponent, encodeURI, encodeURIComponent +]; + +for (var i = 0; i < builtin_funcs.length; i++) { + checkMethod(builtin_funcs[i]); +} + +if (typeof reportCompare == 'function') + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/ecma_5/Function/builtin-no-prototype.js b/js/src/tests/ecma_5/Function/builtin-no-prototype.js new file mode 100644 index 000000000..b5a8cc9f6 --- /dev/null +++ b/js/src/tests/ecma_5/Function/builtin-no-prototype.js @@ -0,0 +1,40 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(undefined, void 0); + +assertEq(Function.prototype.hasOwnProperty('prototype'), false); +assertEq(Function.prototype.prototype, undefined); + +var builtin_ctors = [ + Object, Function, Array, String, Boolean, Number, Date, RegExp, Error, + EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError +]; + +for (var i = 0; i < builtin_ctors.length; i++) { + var c = builtin_ctors[i]; + assertEq(typeof c.prototype, (c === Function) ? "function" : "object"); + assertEq(c.prototype.constructor, c); +} + +var builtin_funcs = [ + eval, isFinite, isNaN, parseFloat, parseInt, + decodeURI, decodeURIComponent, encodeURI, encodeURIComponent +]; + +for (var i = 0; i < builtin_funcs.length; i++) { + assertEq(builtin_funcs[i].hasOwnProperty('prototype'), false); + assertEq(builtin_funcs[i].prototype, undefined); +} + +var names = Object.getOwnPropertyNames(Math); +for (var i = 0; i < names.length; i++) { + var m = Math[names[i]]; + if (typeof m === "function") + assertEq(m.prototype, undefined); +} + +reportCompare(0, 0, "don't crash"); diff --git a/js/src/tests/ecma_5/Function/function-bind.js b/js/src/tests/ecma_5/Function/function-bind.js new file mode 100644 index 000000000..78ee18310 --- /dev/null +++ b/js/src/tests/ecma_5/Function/function-bind.js @@ -0,0 +1,288 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'function-bind.js'; +var BUGNUMBER = 429507; +var summary = "ES5: Function.prototype.bind"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// ad-hoc testing + +assertEq(Function.prototype.hasOwnProperty("bind"), true); + +var bind = Function.prototype.bind; +assertEq(bind.length, 1); + + +var strictReturnThis = function() { "use strict"; return this; }; + +assertEq(strictReturnThis.bind(undefined)(), undefined); +assertEq(strictReturnThis.bind(null)(), null); + +var obj = {}; +assertEq(strictReturnThis.bind(obj)(), obj); + +assertEq(strictReturnThis.bind(NaN)(), NaN); + +assertEq(strictReturnThis.bind(true)(), true); +assertEq(strictReturnThis.bind(false)(), false); + +assertEq(strictReturnThis.bind("foopy")(), "foopy"); + + +// rigorous, step-by-step testing + +function expectThrowTypeError(fun) +{ + try + { + var r = fun(); + throw new Error("didn't throw TypeError, returned " + r); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "didn't throw TypeError, got: " + e); + } +} + +/* + * 1. Let Target be the this value. + * 2. If IsCallable(Target) is false, throw a TypeError exception. + */ +expectThrowTypeError(function() { bind.call(null); }); +expectThrowTypeError(function() { bind.call(undefined); }); +expectThrowTypeError(function() { bind.call(NaN); }); +expectThrowTypeError(function() { bind.call(0); }); +expectThrowTypeError(function() { bind.call(-0); }); +expectThrowTypeError(function() { bind.call(17); }); +expectThrowTypeError(function() { bind.call(42); }); +expectThrowTypeError(function() { bind.call("foobar"); }); +expectThrowTypeError(function() { bind.call(true); }); +expectThrowTypeError(function() { bind.call(false); }); +expectThrowTypeError(function() { bind.call([]); }); +expectThrowTypeError(function() { bind.call({}); }); + + +/* + * 3. Let A be a new (possibly empty) internal list of all of the argument + * values provided after thisArg (arg1, arg2 etc), in order. + * 4. Let F be a new native ECMAScript object . + * 5. Set all the internal methods, except for [[Get]], of F as specified in + * 8.12. + * 6. Set the [[Get]] internal property of F as specified in 15.3.5.4. + * 7. Set the [[TargetFunction]] internal property of F to Target. + * 8. Set the [[BoundThis]] internal property of F to the value of thisArg. + * 9. Set the [[BoundArgs]] internal property of F to A. + */ +// throughout + + +/* 10. Set the [[Class]] internal property of F to "Function". */ +var toString = Object.prototype.toString; +assertEq(toString.call(function(){}), "[object Function]"); +assertEq(toString.call(function a(){}), "[object Function]"); +assertEq(toString.call(function(a){}), "[object Function]"); +assertEq(toString.call(function a(b){}), "[object Function]"); +assertEq(toString.call(function(){}.bind()), "[object Function]"); +assertEq(toString.call(function a(){}.bind()), "[object Function]"); +assertEq(toString.call(function(a){}.bind()), "[object Function]"); +assertEq(toString.call(function a(b){}.bind()), "[object Function]"); + + +/* + * 11. Set the [[Prototype]] internal property of F to the standard built-in + * Function prototype object as specified in 15.3.3.1. + */ +assertEq(Object.getPrototypeOf(bind.call(function(){})), Function.prototype); +assertEq(Object.getPrototypeOf(bind.call(function a(){})), Function.prototype); +assertEq(Object.getPrototypeOf(bind.call(function(a){})), Function.prototype); +assertEq(Object.getPrototypeOf(bind.call(function a(b){})), Function.prototype); + + +/* + * 12. Set the [[Call]] internal property of F as described in 15.3.4.5.1. + */ +var a = Array.bind(1, 2); +assertEq(a().length, 2); +assertEq(a(4).length, 2); +assertEq(a(4, 8).length, 3); + +function t() { return this; } +var bt = t.bind(t); +assertEq(bt(), t); + +function callee() { return arguments.callee; } +var call = callee.bind(); +assertEq(call(), callee); +assertEq(new call(), callee); + + +/* + * 13. Set the [[Construct]] internal property of F as described in 15.3.4.5.2. + */ +function Point(x, y) +{ + this.x = x; + this.y = y; +} +var YAxisPoint = Point.bind(null, 0) + +assertEq(YAxisPoint.hasOwnProperty("prototype"), false); +var p = new YAxisPoint(5); +assertEq(p.x, 0); +assertEq(p.y, 5); +assertEq(p instanceof Point, true); +assertEq(p instanceof YAxisPoint, true); +assertEq(Object.prototype.toString.call(YAxisPoint), "[object Function]"); +assertEq(YAxisPoint.length, 1); + + +/* + * 14. Set the [[HasInstance]] internal property of F as described in + * 15.3.4.5.3. + */ +function JoinArguments() +{ + this.args = Array.prototype.join.call(arguments, ", "); +} + +var Join1 = JoinArguments.bind(null, 1); +var Join2 = Join1.bind(null, 2); +var Join3 = Join2.bind(null, 3); +var Join4 = Join3.bind(null, 4); +var Join5 = Join4.bind(null, 5); +var Join6 = Join5.bind(null, 6); + +var r = new Join6(7); +assertEq(r instanceof Join6, true); +assertEq(r instanceof Join5, true); +assertEq(r instanceof Join4, true); +assertEq(r instanceof Join3, true); +assertEq(r instanceof Join2, true); +assertEq(r instanceof Join1, true); +assertEq(r instanceof JoinArguments, true); +assertEq(r.args, "1, 2, 3, 4, 5, 6, 7"); + + +/* + * 15. If the [[Class]] internal property of Target is "Function", then + * a. Let L be the length property of Target minus the length of A. + * b. Set the length own property of F to either 0 or L, whichever is larger. + * 16. Else set the length own property of F to 0. + */ +function none() { return arguments.length; } +assertEq(none.bind(1, 2)(3, 4), 3); +assertEq(none.bind(1, 2)(), 1); +assertEq(none.bind(1)(2, 3), 2); +assertEq(none.bind().length, 0); +assertEq(none.bind(null).length, 0); +assertEq(none.bind(null, 1).length, 0); +assertEq(none.bind(null, 1, 2).length, 0); + +function one(a) { } +assertEq(one.bind().length, 1); +assertEq(one.bind(null).length, 1); +assertEq(one.bind(null, 1).length, 0); +assertEq(one.bind(null, 1, 2).length, 0); + +// retch +var br = Object.create(null, { length: { value: 0 } }); +try +{ + br = bind.call(/a/g, /a/g, "aaaa"); +} +catch (e) { /* nothing */ } +assertEq(br.length, 0); + + +/* + * 17. Set the attributes of the length own property of F to the values + * specified in 15.3.5.1. + */ +var len1Desc = + Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(), "length"); +assertEq(len1Desc.value, 3); +assertEq(len1Desc.writable, false); +assertEq(len1Desc.enumerable, false); +assertEq(len1Desc.configurable, true); + +var len2Desc = + Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(null, 2), "length"); +assertEq(len2Desc.value, 2); +assertEq(len2Desc.writable, false); +assertEq(len2Desc.enumerable, false); +assertEq(len2Desc.configurable, true); + + +/* + * 18. Set the [[Extensible]] internal property of F to true. + */ +var bound = (function() { }).bind(); + +var isExtensible = Object.isExtensible || function() { return true; }; +assertEq(isExtensible(bound), true); + +bound.foo = 17; +var fooDesc = Object.getOwnPropertyDescriptor(bound, "foo"); +assertEq(fooDesc.value, 17); +assertEq(fooDesc.writable, true); +assertEq(fooDesc.enumerable, true); +assertEq(fooDesc.configurable, true); + + +/* + * Steps 19-21 are removed from ES6, instead implemented through "arguments" and + * "caller" accessors on Function.prototype. So no own properties, but do check + * for the same observable behavior (modulo where the accessors live). + */ +function strict() { "use strict"; } +function nonstrict() {} + +function testBound(fun) +{ + var boundf = fun.bind(); + + assertEq(Object.getOwnPropertyDescriptor(boundf, "arguments"), undefined, + "should be no arguments property"); + assertEq(Object.getOwnPropertyDescriptor(boundf, "caller"), undefined, + "should be no caller property"); + + expectThrowTypeError(function() { return boundf.arguments; }); + expectThrowTypeError(function() { return boundf.caller; }); +} + +testBound(strict); +testBound(nonstrict); + +assertEq((function unbound(){"body"}).bind().toString(), `function bound unbound() { + [native code] +}`); + +assertEq((function unbound(){"body"}).bind().toSource(), `function bound unbound() { + [native code] +}`); + +assertEq(uneval((function unbound(){"body"}).bind()), `function bound unbound() { + [native code] +}`); + + +/* 22. Return F. */ +var passim = function p(){}.bind(1); +assertEq(typeof passim, "function"); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/function-call.js b/js/src/tests/ecma_5/Function/function-call.js new file mode 100644 index 000000000..756b58384 --- /dev/null +++ b/js/src/tests/ecma_5/Function/function-call.js @@ -0,0 +1,134 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 575535; +var summary = 'Function.prototype.call'; +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectTypeError(fun, msg) +{ + try + { + fun(); + assertEq(true, false, "should have thrown a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, msg + "; instead threw " + e); + } +} + +function fun() { } + +var global = this; + +assertEq(Function.prototype.call.length, 1); + + +/* Step 1. */ +var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}]; +for (var i = 0, sz = nonfuns.length; i < sz; i++) +{ + var f = function() + { + Function.prototype.call.apply(nonfuns[i]); + }; + var msg = + "expected TypeError calling Function.prototype.call with uncallable this"; + expectTypeError(f, msg); +} + + +/* Steps 2-4. */ +function none() +{ + assertEq(this, global, "bad this"); + assertEq(arguments.length, 0, "wrong arguments"); +} + +none.call(); +none.call(undefined); +none.call(null); + +var seenThis; +function strictNone() +{ + "use strict"; + assertEq(this, seenThis, "bad this"); + assertEq(arguments.length, 0, "wrong arguments"); +} + +seenThis = undefined; +strictNone.call(); +strictNone.call(undefined); + +seenThis = null; +strictNone.call(null); + +seenThis = 17; +strictNone.call(17); + +var seenThisBox, args; +function some() +{ + assertEq(this instanceof seenThisBox, true, + "this not instanceof " + seenThisBox); + assertEq(this.valueOf(), seenThis, + "wrong this valueOf()"); + assertEq(arguments.length, args.length, "wrong arguments count"); + for (var i = 0; i < args.length; i++) + assertEq(arguments[i], args[i], "wrong argument " + i); +} + +seenThis = false; +seenThisBox = Boolean; +args = [8, 6, 7, NaN, undefined, 0.3]; +some.call(false, 8, 6, 7, NaN, undefined, 0.3); + +var obj = {}; + +seenThis = "foo"; +seenThisBox = String; +args = [obj]; +some.call("foo", obj); + +seenThis = obj; +seenThisBox = Object; +some.call(obj, obj); + +function strictSome() +{ + "use strict"; + assertEq(this, seenThis, "wrong this"); + assertEq(arguments.length, args.length, "wrong arguments count"); + for (var i = 0; i < args.length; i++) + assertEq(arguments[i], args[i], "wrong argument " + i); +} + +seenThis = NaN; +args = [8, 6, 7, NaN, undefined, 0.3]; +strictSome.call(NaN, 8, 6, 7, NaN, undefined, 0.3); + +seenThis = "foo"; +args = [obj]; +strictSome.call("foo", obj); + +seenThis = obj; +strictSome.call(obj, obj); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/function-caller.js b/js/src/tests/ecma_5/Function/function-caller.js new file mode 100644 index 000000000..2b0812d4f --- /dev/null +++ b/js/src/tests/ecma_5/Function/function-caller.js @@ -0,0 +1,45 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'function-caller.js'; +var BUGNUMBER = 514581; +var summary = "Function.prototype.caller should throw a TypeError for " + + "strict-mode functions"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// behavior + +function expectTypeError(fun) +{ + try + { + fun(); + throw new Error("didn't throw"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "expected TypeError calling function" + + ("name" in fun ? " " + fun.name : "") + ", instead got: " + e); + } +} + +function bar() { "use strict"; } +expectTypeError(function barCaller() { bar.caller; }); + +function baz() { "use strict"; return 17; } +expectTypeError(function bazCaller() { baz.caller; }); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/redefine-arguments-length.js b/js/src/tests/ecma_5/Function/redefine-arguments-length.js new file mode 100644 index 000000000..ad9ae742f --- /dev/null +++ b/js/src/tests/ecma_5/Function/redefine-arguments-length.js @@ -0,0 +1,65 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'redefine-arguments-length.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 539766; +var summary = + "Object.defineProperty sets arguments.length without setting the " + + "length-overridden bit"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function test_JSOP_ARGCNT() +{ + var length = "length"; + Object.defineProperty(arguments, length, { value: 17 }); + assertEq(arguments.length, 17); + assertEq(arguments[length], 17); +} +test_JSOP_ARGCNT(); + +function test_js_fun_apply() +{ + var length = "length"; + Object.defineProperty(arguments, length, { value: 17 }); + + function fun() + { + assertEq(arguments.length, 17); + assertEq(arguments[length], 17); + assertEq(arguments[0], "foo"); + for (var i = 1; i < 17; i++) + assertEq(arguments[i], undefined); + } + fun.apply(null, arguments); +} +test_js_fun_apply("foo"); + +function test_array_toString_sub_1() +{ + Object.defineProperty(arguments, "length", { value: 1 }); + arguments.join = [].join; + assertEq([].toString.call(arguments), "1"); +} +test_array_toString_sub_1(1, 2); + +function test_array_toString_sub_2() +{ + Object.defineProperty(arguments, "length", { value: 1 }); + assertEq([].toLocaleString.call(arguments), "1"); +} +test_array_toString_sub_2(1, 2); + + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Function/shell.js b/js/src/tests/ecma_5/Function/shell.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/Function/shell.js diff --git a/js/src/tests/ecma_5/Function/strict-arguments.js b/js/src/tests/ecma_5/Function/strict-arguments.js new file mode 100644 index 000000000..fce5f756c --- /dev/null +++ b/js/src/tests/ecma_5/Function/strict-arguments.js @@ -0,0 +1,453 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'strict-arguments.js'; +var BUGNUMBER = 516255; +var summary = + "ES5 strict mode: arguments objects of strict mode functions must copy " + + "argument values"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function arrayEvery(arr, fun) +{ + return Array.prototype.every.call(arr, fun); +} + +function arraysEqual(a1, a2) +{ + return a1.length === a2.length && + arrayEvery(a1, function(v, i) { return v === a2[i]; }); +} + + +/************************ + * NON-STRICT ARGUMENTS * + ************************/ + +var obj = {}; + +function noargs() { return arguments; } + +assertEq(arraysEqual(noargs(), []), true); +assertEq(arraysEqual(noargs(1), [1]), true); +assertEq(arraysEqual(noargs(2, obj, 8), [2, obj, 8]), true); + +function args(a) { return arguments; } + +assertEq(arraysEqual(args(), []), true); +assertEq(arraysEqual(args(1), [1]), true); +assertEq(arraysEqual(args(1, obj), [1, obj]), true); +assertEq(arraysEqual(args("foopy"), ["foopy"]), true); + +function assign(a) +{ + a = 17; + return arguments; +} + +assertEq(arraysEqual(assign(1), [17]), true); + +function getLaterAssign(a) +{ + var o = arguments; + a = 17; + return o; +} + +assertEq(arraysEqual(getLaterAssign(1), [17]), true); + +function assignElementGetParameter(a) +{ + arguments[0] = 17; + return a; +} + +assertEq(assignElementGetParameter(42), 17); + +function assignParameterGetElement(a) +{ + a = 17; + return arguments[0]; +} + +assertEq(assignParameterGetElement(42), 17); + +function assignArgSub(x, y) +{ + arguments[0] = 3; + return arguments[0]; +} + +assertEq(assignArgSub(1), 3); + +function assignArgSubParamUse(x, y) +{ + arguments[0] = 3; + assertEq(x, 3); + return arguments[0]; +} + +assertEq(assignArgSubParamUse(1), 3); + +function assignArgumentsElement(x, y) +{ + arguments[0] = 3; + return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations +} + +assertEq(assignArgumentsElement(1), 3); + +function assignArgumentsElementParamUse(x, y) +{ + arguments[0] = 3; + assertEq(x, 3); + return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations +} + +assertEq(assignArgumentsElementParamUse(1), 3); + +/******************** + * STRICT ARGUMENTS * + ********************/ + +function strictNoargs() +{ + "use strict"; + return arguments; +} + +assertEq(arraysEqual(strictNoargs(), []), true); +assertEq(arraysEqual(strictNoargs(1), [1]), true); +assertEq(arraysEqual(strictNoargs(1, obj), [1, obj]), true); + +function strictArgs(a) +{ + "use strict"; + return arguments; +} + +assertEq(arraysEqual(strictArgs(), []), true); +assertEq(arraysEqual(strictArgs(1), [1]), true); +assertEq(arraysEqual(strictArgs(1, obj), [1, obj]), true); + +function strictAssign(a) +{ + "use strict"; + a = 17; + return arguments; +} + +assertEq(arraysEqual(strictAssign(), []), true); +assertEq(arraysEqual(strictAssign(1), [1]), true); +assertEq(arraysEqual(strictAssign(1, obj), [1, obj]), true); + +var upper; +function strictAssignAfter(a) +{ + "use strict"; + upper = arguments; + a = 42; + return upper; +} + +assertEq(arraysEqual(strictAssignAfter(), []), true); +assertEq(arraysEqual(strictAssignAfter(17), [17]), true); +assertEq(arraysEqual(strictAssignAfter(obj), [obj]), true); + +function strictMaybeAssignOuterParam(p) +{ + "use strict"; + function inner() { p = 17; } + return arguments; +} + +assertEq(arraysEqual(strictMaybeAssignOuterParam(), []), true); +assertEq(arraysEqual(strictMaybeAssignOuterParam(42), [42]), true); +assertEq(arraysEqual(strictMaybeAssignOuterParam(obj), [obj]), true); + +function strictAssignOuterParam(p) +{ + "use strict"; + function inner() { p = 17; } + inner(); + return arguments; +} + +assertEq(arraysEqual(strictAssignOuterParam(), []), true); +assertEq(arraysEqual(strictAssignOuterParam(17), [17]), true); +assertEq(arraysEqual(strictAssignOuterParam(obj), [obj]), true); + +function strictAssignOuterParamPSYCH(p) +{ + "use strict"; + function inner(p) { p = 17; } + inner(); + return arguments; +} + +assertEq(arraysEqual(strictAssignOuterParamPSYCH(), []), true); +assertEq(arraysEqual(strictAssignOuterParamPSYCH(17), [17]), true); +assertEq(arraysEqual(strictAssignOuterParamPSYCH(obj), [obj]), true); + +function strictEval(code, p) +{ + "use strict"; + eval(code); + return arguments; +} + +assertEq(arraysEqual(strictEval("1", 2), ["1", 2]), true); +assertEq(arraysEqual(strictEval("arguments"), ["arguments"]), true); +assertEq(arraysEqual(strictEval("p = 2"), ["p = 2"]), true); +assertEq(arraysEqual(strictEval("p = 2", 17), ["p = 2", 17]), true); +assertEq(arraysEqual(strictEval("arguments[0] = 17"), [17]), true); +assertEq(arraysEqual(strictEval("arguments[0] = 17", 42), [17, 42]), true); + +function strictMaybeNestedEval(code, p) +{ + "use strict"; + function inner() { eval(code); } + return arguments; +} + +assertEq(arraysEqual(strictMaybeNestedEval("1", 2), ["1", 2]), true); +assertEq(arraysEqual(strictMaybeNestedEval("arguments"), ["arguments"]), true); +assertEq(arraysEqual(strictMaybeNestedEval("p = 2"), ["p = 2"]), true); +assertEq(arraysEqual(strictMaybeNestedEval("p = 2", 17), ["p = 2", 17]), true); + +function strictNestedEval(code, p) +{ + "use strict"; + function inner() { eval(code); } + inner(); + return arguments; +} + +assertEq(arraysEqual(strictNestedEval("1", 2), ["1", 2]), true); +assertEq(arraysEqual(strictNestedEval("arguments"), ["arguments"]), true); +assertEq(arraysEqual(strictNestedEval("p = 2"), ["p = 2"]), true); +assertEq(arraysEqual(strictNestedEval("p = 2", 17), ["p = 2", 17]), true); +assertEq(arraysEqual(strictNestedEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); +assertEq(arraysEqual(strictNestedEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); + +function strictAssignArguments(a) +{ + "use strict"; + arguments[0] = 42; + return a; +} + +assertEq(strictAssignArguments(), undefined); +assertEq(strictAssignArguments(obj), obj); +assertEq(strictAssignArguments(17), 17); + +function strictAssignParameterGetElement(a) +{ + "use strict"; + a = 17; + return arguments[0]; +} + +assertEq(strictAssignParameterGetElement(42), 42); + +function strictAssignArgSub(x, y) +{ + "use strict"; + arguments[0] = 3; + return arguments[0]; +} + +assertEq(strictAssignArgSub(1), 3); + +function strictAssignArgSubParamUse(x, y) +{ + "use strict"; + arguments[0] = 3; + assertEq(x, 1); + return arguments[0]; +} + +assertEq(strictAssignArgSubParamUse(1), 3); + +function strictAssignArgumentsElement(x, y) +{ + "use strict"; + arguments[0] = 3; + return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations +} + +assertEq(strictAssignArgumentsElement(1), 3); + +function strictAssignArgumentsElementParamUse(x, y) +{ + "use strict"; + arguments[0] = 3; + assertEq(x, 1); + return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations +} + +assertEq(strictAssignArgumentsElementParamUse(1), 3); + +function strictNestedAssignShadowVar(p) +{ + "use strict"; + function inner() + { + var p = 12; + function innermost() { p = 1776; return 12; } + return innermost(); + } + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true); + +function strictNestedAssignShadowCatch(p) +{ + "use strict"; + function inner() + { + try + { + } + catch (p) + { + var f = function innermost() { p = 1776; return 12; }; + f(); + } + } + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowCatch(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowCatch(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowCatch(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowCatch(obj), [obj]), true); + +function strictNestedAssignShadowCatchCall(p) +{ + "use strict"; + function inner() + { + try + { + } + catch (p) + { + var f = function innermost() { p = 1776; return 12; }; + f(); + } + } + inner(); + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowCatchCall(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowCatchCall(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowCatchCall(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowCatchCall(obj), [obj]), true); + +function strictNestedAssignShadowFunction(p) +{ + "use strict"; + function inner() + { + function p() { } + p = 1776; + } + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowFunction(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowFunction(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunction(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunction(obj), [obj]), true); + +function strictNestedAssignShadowFunctionCall(p) +{ + "use strict"; + function inner() + { + function p() { } + p = 1776; + } + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(obj), [obj]), true); + +function strictNestedShadowAndMaybeEval(code, p) +{ + "use strict"; + function inner(p) { eval(code); } + return arguments; +} + +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("1", 2), ["1", 2]), true); +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments"), ["arguments"]), true); +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2"), ["p = 2"]), true); +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2", 17), ["p = 2", 17]), true); +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); +assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); + +function strictNestedShadowAndEval(code, p) +{ + "use strict"; + function inner(p) { eval(code); } + return arguments; +} + +assertEq(arraysEqual(strictNestedShadowAndEval("1", 2), ["1", 2]), true); +assertEq(arraysEqual(strictNestedShadowAndEval("arguments"), ["arguments"]), true); +assertEq(arraysEqual(strictNestedShadowAndEval("p = 2"), ["p = 2"]), true); +assertEq(arraysEqual(strictNestedShadowAndEval("p = 2", 17), ["p = 2", 17]), true); +assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); +assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); + +function strictEvalContainsMutation(code) +{ + "use strict"; + return eval(code); +} + +assertEq(arraysEqual(strictEvalContainsMutation("code = 17; arguments"), ["code = 17; arguments"]), true); +assertEq(arraysEqual(strictEvalContainsMutation("arguments[0] = 17; arguments"), [17]), true); +assertEq(strictEvalContainsMutation("arguments[0] = 17; code"), "arguments[0] = 17; code"); + +function strictNestedAssignShadowFunctionName(p) +{ + "use strict"; + function inner() + { + function p() { p = 1776; } + p(); + } + inner(); + return arguments; +} + +assertEq(arraysEqual(strictNestedAssignShadowFunctionName(), []), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionName(99), [99]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionName(""), [""]), true); +assertEq(arraysEqual(strictNestedAssignShadowFunctionName(obj), [obj]), true); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); |