summaryrefslogtreecommitdiff
path: root/js/src/tests/ecma_5/Function/15.3.4.3-01.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_5/Function/15.3.4.3-01.js')
-rw-r--r--js/src/tests/ecma_5/Function/15.3.4.3-01.js245
1 files changed, 245 insertions, 0 deletions
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 0000000..955d773
--- /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!");