js/src/tests/ecma_5/Function/15.3.4.3-01.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Any copyright is dedicated to the Public Domain.
michael@0 3 * http://creativecommons.org/licenses/publicdomain/
michael@0 4 * Contributor:
michael@0 5 * Jeff Walden <jwalden+code@mit.edu>
michael@0 6 */
michael@0 7
michael@0 8 //-----------------------------------------------------------------------------
michael@0 9 var BUGNUMBER = 562448;
michael@0 10 var summary = 'Function.prototype.apply should accept any arraylike arguments';
michael@0 11 print(BUGNUMBER + ": " + summary);
michael@0 12
michael@0 13 /**************
michael@0 14 * BEGIN TEST *
michael@0 15 **************/
michael@0 16
michael@0 17 function expectTypeError(fun, msg)
michael@0 18 {
michael@0 19 try
michael@0 20 {
michael@0 21 fun();
michael@0 22 assertEq(true, false, "should have thrown a TypeError");
michael@0 23 }
michael@0 24 catch (e)
michael@0 25 {
michael@0 26 assertEq(e instanceof TypeError, true, msg + "; instead threw " + e);
michael@0 27 }
michael@0 28 }
michael@0 29
michael@0 30 function fun() { }
michael@0 31
michael@0 32 var global = this;
michael@0 33
michael@0 34
michael@0 35 /* Step 1. */
michael@0 36 var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}];
michael@0 37 for (var i = 0, sz = nonfuns.length; i < sz; i++)
michael@0 38 {
michael@0 39 var f = function()
michael@0 40 {
michael@0 41 Function.prototype.apply.apply(nonfuns[i], [1, 2, 3]);
michael@0 42 };
michael@0 43 var msg =
michael@0 44 "expected TypeError calling Function.prototype.apply with uncallable this";
michael@0 45 expectTypeError(f, msg);
michael@0 46 }
michael@0 47
michael@0 48
michael@0 49 /* Step 2. */
michael@0 50 var thisObj = {};
michael@0 51
michael@0 52 var currentThis, currentThisBox;
michael@0 53 function funLength()
michael@0 54 {
michael@0 55 assertEq(arguments.length, 0, "should have been called with no arguments");
michael@0 56 assertEq(this, currentThis, "wrong this");
michael@0 57 }
michael@0 58 function strictFunLength()
michael@0 59 {
michael@0 60 "use strict";
michael@0 61 assertEq(arguments.length, 0, "should have been called with no arguments");
michael@0 62 assertEq(this, currentThis, "wrong this");
michael@0 63 }
michael@0 64
michael@0 65 currentThis = global;
michael@0 66 funLength.apply();
michael@0 67 funLength.apply(undefined);
michael@0 68 funLength.apply(undefined, undefined);
michael@0 69 funLength.apply(undefined, null);
michael@0 70
michael@0 71 currentThis = undefined;
michael@0 72 strictFunLength.apply();
michael@0 73 strictFunLength.apply(undefined);
michael@0 74 strictFunLength.apply(undefined, undefined);
michael@0 75 strictFunLength.apply(undefined, null);
michael@0 76
michael@0 77 currentThis = null;
michael@0 78 strictFunLength.apply(null);
michael@0 79 strictFunLength.apply(null, undefined);
michael@0 80 strictFunLength.apply(null, null);
michael@0 81
michael@0 82 currentThis = thisObj;
michael@0 83 funLength.apply(thisObj);
michael@0 84 funLength.apply(thisObj, null);
michael@0 85 funLength.apply(thisObj, undefined);
michael@0 86 strictFunLength.apply(thisObj);
michael@0 87 strictFunLength.apply(thisObj, null);
michael@0 88 strictFunLength.apply(thisObj, undefined);
michael@0 89
michael@0 90 currentThis = 17;
michael@0 91 strictFunLength.apply(17);
michael@0 92 strictFunLength.apply(17, null);
michael@0 93 strictFunLength.apply(17, undefined);
michael@0 94
michael@0 95 function funThisPrimitive()
michael@0 96 {
michael@0 97 assertEq(arguments.length, 0, "should have been called with no arguments");
michael@0 98 assertEq(this instanceof currentThisBox, true,
michael@0 99 "this not instanceof " + currentThisBox);
michael@0 100 assertEq(this.valueOf(), currentThis,
michael@0 101 "wrong this valueOf()");
michael@0 102 }
michael@0 103
michael@0 104 currentThis = 17;
michael@0 105 currentThisBox = Number;
michael@0 106 funThisPrimitive.apply(17);
michael@0 107 funThisPrimitive.apply(17, undefined);
michael@0 108 funThisPrimitive.apply(17, null);
michael@0 109
michael@0 110 currentThis = "foopy";
michael@0 111 currentThisBox = String;
michael@0 112 funThisPrimitive.apply("foopy");
michael@0 113 funThisPrimitive.apply("foopy", undefined);
michael@0 114 funThisPrimitive.apply("foopy", null);
michael@0 115
michael@0 116 currentThis = false;
michael@0 117 currentThisBox = Boolean;
michael@0 118 funThisPrimitive.apply(false);
michael@0 119 funThisPrimitive.apply(false, undefined);
michael@0 120 funThisPrimitive.apply(false, null);
michael@0 121
michael@0 122
michael@0 123 /* Step 3. */
michael@0 124 var nonobjs = [1, -1, 2.5, "[[Call]]", true, false];
michael@0 125 for (var i = 0, sz = nonobjs.length; i < sz; i++)
michael@0 126 {
michael@0 127 var f = function() { fun.apply(thisObj, nonobjs[i]); };
michael@0 128 var msg = "should have thrown a TypeError with non-object arguments";
michael@0 129 expectTypeError(f, msg);
michael@0 130 }
michael@0 131
michael@0 132
michael@0 133 /* Step 4. */
michael@0 134 var args = { get length() { throw 42; } };
michael@0 135 try
michael@0 136 {
michael@0 137 fun.apply(thisObj, args);
michael@0 138 }
michael@0 139 catch (e)
michael@0 140 {
michael@0 141 assertEq(e, 42, "didn't throw result of [[Get]] on arguments object");
michael@0 142 }
michael@0 143
michael@0 144
michael@0 145 /*
michael@0 146 * NB: There was an erratum removing the steps numbered 5 and 7 in the original
michael@0 147 * version of ES5; see also the comments in js_fun_apply.
michael@0 148 */
michael@0 149
michael@0 150 /* Step 5. */
michael@0 151 var called = false;
michael@0 152 var argsObjectLength =
michael@0 153 { length: { valueOf: function() { called = true; return 17; } } };
michael@0 154
michael@0 155 fun.apply({}, argsObjectLength);
michael@0 156 assertEq(called, true, "should have been set in valueOf called via ToUint32");
michael@0 157
michael@0 158 var upvar = "unset";
michael@0 159 var argsObjectPrimitiveLength =
michael@0 160 {
michael@0 161 length:
michael@0 162 {
michael@0 163 valueOf: function() { upvar = "valueOf"; return {}; },
michael@0 164 toString: function()
michael@0 165 {
michael@0 166 upvar = upvar === "valueOf" ? "both" : "toString";
michael@0 167 return 17;
michael@0 168 }
michael@0 169 }
michael@0 170 };
michael@0 171 fun.apply({}, argsObjectPrimitiveLength);
michael@0 172 assertEq(upvar, "both", "didn't call all hooks properly");
michael@0 173
michael@0 174
michael@0 175 /* Step 6-9. */
michael@0 176 var seenThis, res, steps;
michael@0 177 var argsAccessors =
michael@0 178 {
michael@0 179 length: 4,
michael@0 180 get 0() { steps.push("0"); return 1; },
michael@0 181 get 1() { steps.push("1"); return 2; },
michael@0 182 // make sure values shine through holes
michael@0 183 get 3() { steps.push("3"); return 8; },
michael@0 184 };
michael@0 185
michael@0 186 Object.prototype[2] = 729;
michael@0 187
michael@0 188 seenThis = "not seen";
michael@0 189 function argsAsArray()
michael@0 190 {
michael@0 191 seenThis = this;
michael@0 192 steps.push(Math.PI);
michael@0 193 return Array.prototype.map.call(arguments, function(v) { return v; });
michael@0 194 }
michael@0 195
michael@0 196 steps = [];
michael@0 197 res = argsAsArray.apply(thisObj, argsAccessors);
michael@0 198 assertEq(seenThis, thisObj, "saw wrong this");
michael@0 199
michael@0 200 assertEq(steps.length, 4, "wrong steps: " + steps);
michael@0 201 assertEq(steps[0], "0", "bad step 0");
michael@0 202 assertEq(steps[1], "1", "bad step 1");
michael@0 203 assertEq(steps[2], "3", "bad step 3");
michael@0 204 assertEq(steps[3], Math.PI, "bad last step");
michael@0 205
michael@0 206 assertEq(res.length, 4, "wrong return: " + res);
michael@0 207 assertEq(res[0], 1, "wrong ret[0]");
michael@0 208 assertEq(res[1], 2, "wrong ret[0]");
michael@0 209 assertEq(res[2], 729, "wrong ret[0]");
michael@0 210 assertEq(res[3], 8, "wrong ret[0]");
michael@0 211
michael@0 212 seenThis = "not seen";
michael@0 213 function strictArgsAsArray()
michael@0 214 {
michael@0 215 "use strict";
michael@0 216 seenThis = this;
michael@0 217 steps.push(NaN);
michael@0 218 return Array.prototype.map.call(arguments, function(v) { return v; });
michael@0 219 }
michael@0 220
michael@0 221 steps = [];
michael@0 222 res = strictArgsAsArray.apply(null, argsAccessors);
michael@0 223 assertEq(seenThis, null, "saw wrong this");
michael@0 224
michael@0 225 assertEq(steps.length, 4, "wrong steps: " + steps);
michael@0 226 assertEq(steps[0], "0", "bad step 0");
michael@0 227 assertEq(steps[1], "1", "bad step 1");
michael@0 228 assertEq(steps[2], "3", "bad step 3");
michael@0 229 assertEq(steps[3], 0 / 0, "bad last step");
michael@0 230
michael@0 231 assertEq(res.length, 4, "wrong return: " + res);
michael@0 232 assertEq(res[0], 1, "wrong ret[0]");
michael@0 233 assertEq(res[1], 2, "wrong ret[0]");
michael@0 234 assertEq(res[2], 729, "wrong ret[0]");
michael@0 235 assertEq(res[3], 8, "wrong ret[0]");
michael@0 236
michael@0 237 strictArgsAsArray.apply(17, argsAccessors);
michael@0 238 assertEq(seenThis, 17, "saw wrong this");
michael@0 239
michael@0 240 /******************************************************************************/
michael@0 241
michael@0 242 if (typeof reportCompare === "function")
michael@0 243 reportCompare(true, true);
michael@0 244
michael@0 245 print("All tests passed!");

mercurial