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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/tests/ecma_5/Function/15.3.4.3-01.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,245 @@
     1.4 +/*
     1.5 + * Any copyright is dedicated to the Public Domain.
     1.6 + * http://creativecommons.org/licenses/publicdomain/
     1.7 + * Contributor:
     1.8 + *   Jeff Walden <jwalden+code@mit.edu>
     1.9 + */
    1.10 +
    1.11 +//-----------------------------------------------------------------------------
    1.12 +var BUGNUMBER = 562448;
    1.13 +var summary = 'Function.prototype.apply should accept any arraylike arguments';
    1.14 +print(BUGNUMBER + ": " + summary);
    1.15 +
    1.16 +/**************
    1.17 + * BEGIN TEST *
    1.18 + **************/
    1.19 +
    1.20 +function expectTypeError(fun, msg)
    1.21 +{
    1.22 +  try
    1.23 +  {
    1.24 +    fun();
    1.25 +    assertEq(true, false, "should have thrown a TypeError");
    1.26 +  }
    1.27 +  catch (e)
    1.28 +  {
    1.29 +    assertEq(e instanceof TypeError, true, msg + "; instead threw " + e);
    1.30 +  }
    1.31 +}
    1.32 +
    1.33 +function fun() { }
    1.34 +
    1.35 +var global = this;
    1.36 +
    1.37 +
    1.38 +/* Step 1. */
    1.39 +var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}];
    1.40 +for (var i = 0, sz = nonfuns.length; i < sz; i++)
    1.41 +{
    1.42 +  var f = function()
    1.43 +  {
    1.44 +    Function.prototype.apply.apply(nonfuns[i], [1, 2, 3]);
    1.45 +  };
    1.46 +  var msg =
    1.47 +    "expected TypeError calling Function.prototype.apply with uncallable this";
    1.48 +  expectTypeError(f, msg);
    1.49 +}
    1.50 +
    1.51 +
    1.52 +/* Step 2. */
    1.53 +var thisObj = {};
    1.54 +
    1.55 +var currentThis, currentThisBox;
    1.56 +function funLength()
    1.57 +{
    1.58 +  assertEq(arguments.length, 0, "should have been called with no arguments");
    1.59 +  assertEq(this, currentThis, "wrong this");
    1.60 +}
    1.61 +function strictFunLength()
    1.62 +{
    1.63 +  "use strict";
    1.64 +  assertEq(arguments.length, 0, "should have been called with no arguments");
    1.65 +  assertEq(this, currentThis, "wrong this");
    1.66 +}
    1.67 +
    1.68 +currentThis = global;
    1.69 +funLength.apply();
    1.70 +funLength.apply(undefined);
    1.71 +funLength.apply(undefined, undefined);
    1.72 +funLength.apply(undefined, null);
    1.73 +
    1.74 +currentThis = undefined;
    1.75 +strictFunLength.apply();
    1.76 +strictFunLength.apply(undefined);
    1.77 +strictFunLength.apply(undefined, undefined);
    1.78 +strictFunLength.apply(undefined, null);
    1.79 +
    1.80 +currentThis = null;
    1.81 +strictFunLength.apply(null);
    1.82 +strictFunLength.apply(null, undefined);
    1.83 +strictFunLength.apply(null, null);
    1.84 +
    1.85 +currentThis = thisObj;
    1.86 +funLength.apply(thisObj);
    1.87 +funLength.apply(thisObj, null);
    1.88 +funLength.apply(thisObj, undefined);
    1.89 +strictFunLength.apply(thisObj);
    1.90 +strictFunLength.apply(thisObj, null);
    1.91 +strictFunLength.apply(thisObj, undefined);
    1.92 +
    1.93 +currentThis = 17;
    1.94 +strictFunLength.apply(17);
    1.95 +strictFunLength.apply(17, null);
    1.96 +strictFunLength.apply(17, undefined);
    1.97 +
    1.98 +function funThisPrimitive()
    1.99 +{
   1.100 +  assertEq(arguments.length, 0, "should have been called with no arguments");
   1.101 +  assertEq(this instanceof currentThisBox, true,
   1.102 +           "this not instanceof " + currentThisBox);
   1.103 +  assertEq(this.valueOf(), currentThis,
   1.104 +           "wrong this valueOf()");
   1.105 +}
   1.106 +
   1.107 +currentThis = 17;
   1.108 +currentThisBox = Number;
   1.109 +funThisPrimitive.apply(17);
   1.110 +funThisPrimitive.apply(17, undefined);
   1.111 +funThisPrimitive.apply(17, null);
   1.112 +
   1.113 +currentThis = "foopy";
   1.114 +currentThisBox = String;
   1.115 +funThisPrimitive.apply("foopy");
   1.116 +funThisPrimitive.apply("foopy", undefined);
   1.117 +funThisPrimitive.apply("foopy", null);
   1.118 +
   1.119 +currentThis = false;
   1.120 +currentThisBox = Boolean;
   1.121 +funThisPrimitive.apply(false);
   1.122 +funThisPrimitive.apply(false, undefined);
   1.123 +funThisPrimitive.apply(false, null);
   1.124 +
   1.125 +
   1.126 +/* Step 3. */
   1.127 +var nonobjs = [1, -1, 2.5, "[[Call]]", true, false];
   1.128 +for (var i = 0, sz = nonobjs.length; i < sz; i++)
   1.129 +{
   1.130 +  var f = function() { fun.apply(thisObj, nonobjs[i]); };
   1.131 +  var msg = "should have thrown a TypeError with non-object arguments";
   1.132 +  expectTypeError(f, msg);
   1.133 +}
   1.134 +
   1.135 +
   1.136 +/* Step 4. */
   1.137 +var args = { get length() { throw 42; } };
   1.138 +try
   1.139 +{
   1.140 +  fun.apply(thisObj, args);
   1.141 +}
   1.142 +catch (e)
   1.143 +{
   1.144 +  assertEq(e, 42, "didn't throw result of [[Get]] on arguments object");
   1.145 +}
   1.146 +
   1.147 +
   1.148 +/*
   1.149 + * NB: There was an erratum removing the steps numbered 5 and 7 in the original
   1.150 + *     version of ES5; see also the comments in js_fun_apply.
   1.151 + */
   1.152 +
   1.153 +/* Step 5. */
   1.154 +var called = false;
   1.155 +var argsObjectLength =
   1.156 +  { length: { valueOf: function() { called = true; return 17; } } };
   1.157 +
   1.158 +fun.apply({}, argsObjectLength);
   1.159 +assertEq(called, true, "should have been set in valueOf called via ToUint32");
   1.160 +
   1.161 +var upvar = "unset";
   1.162 +var argsObjectPrimitiveLength =
   1.163 +  {
   1.164 +    length:
   1.165 +      {
   1.166 +        valueOf: function() { upvar = "valueOf"; return {}; },
   1.167 +        toString: function()
   1.168 +        {
   1.169 +          upvar = upvar === "valueOf" ? "both" : "toString";
   1.170 +          return 17;
   1.171 +        }
   1.172 +      }
   1.173 +  };
   1.174 +fun.apply({}, argsObjectPrimitiveLength);
   1.175 +assertEq(upvar, "both", "didn't call all hooks properly");
   1.176 +
   1.177 +
   1.178 +/* Step 6-9. */
   1.179 +var seenThis, res, steps;
   1.180 +var argsAccessors =
   1.181 +  {
   1.182 +    length: 4,
   1.183 +    get 0() { steps.push("0"); return 1; },
   1.184 +    get 1() { steps.push("1"); return 2; },
   1.185 +    // make sure values shine through holes
   1.186 +    get 3() { steps.push("3"); return 8; },
   1.187 +  };
   1.188 +
   1.189 +Object.prototype[2] = 729;
   1.190 +
   1.191 +seenThis = "not seen";
   1.192 +function argsAsArray()
   1.193 +{
   1.194 +  seenThis = this;
   1.195 +  steps.push(Math.PI);
   1.196 +  return Array.prototype.map.call(arguments, function(v) { return v; });
   1.197 +}
   1.198 +
   1.199 +steps = [];
   1.200 +res = argsAsArray.apply(thisObj, argsAccessors);
   1.201 +assertEq(seenThis, thisObj, "saw wrong this");
   1.202 +
   1.203 +assertEq(steps.length, 4, "wrong steps: " + steps);
   1.204 +assertEq(steps[0], "0", "bad step 0");
   1.205 +assertEq(steps[1], "1", "bad step 1");
   1.206 +assertEq(steps[2], "3", "bad step 3");
   1.207 +assertEq(steps[3], Math.PI, "bad last step");
   1.208 +
   1.209 +assertEq(res.length, 4, "wrong return: " + res);
   1.210 +assertEq(res[0], 1, "wrong ret[0]");
   1.211 +assertEq(res[1], 2, "wrong ret[0]");
   1.212 +assertEq(res[2], 729, "wrong ret[0]");
   1.213 +assertEq(res[3], 8, "wrong ret[0]");
   1.214 +
   1.215 +seenThis = "not seen";
   1.216 +function strictArgsAsArray()
   1.217 +{
   1.218 +  "use strict";
   1.219 +  seenThis = this;
   1.220 +  steps.push(NaN);
   1.221 +  return Array.prototype.map.call(arguments, function(v) { return v; });
   1.222 +}
   1.223 +
   1.224 +steps = [];
   1.225 +res = strictArgsAsArray.apply(null, argsAccessors);
   1.226 +assertEq(seenThis, null, "saw wrong this");
   1.227 +
   1.228 +assertEq(steps.length, 4, "wrong steps: " + steps);
   1.229 +assertEq(steps[0], "0", "bad step 0");
   1.230 +assertEq(steps[1], "1", "bad step 1");
   1.231 +assertEq(steps[2], "3", "bad step 3");
   1.232 +assertEq(steps[3], 0 / 0, "bad last step");
   1.233 +
   1.234 +assertEq(res.length, 4, "wrong return: " + res);
   1.235 +assertEq(res[0], 1, "wrong ret[0]");
   1.236 +assertEq(res[1], 2, "wrong ret[0]");
   1.237 +assertEq(res[2], 729, "wrong ret[0]");
   1.238 +assertEq(res[3], 8, "wrong ret[0]");
   1.239 +
   1.240 +strictArgsAsArray.apply(17, argsAccessors);
   1.241 +assertEq(seenThis, 17, "saw wrong this");
   1.242 +
   1.243 +/******************************************************************************/
   1.244 +
   1.245 +if (typeof reportCompare === "function")
   1.246 +  reportCompare(true, true);
   1.247 +
   1.248 +print("All tests passed!");

mercurial