js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.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.

     1 /*
     2  * Any copyright is dedicated to the Public Domain.
     3  * http://creativecommons.org/licenses/publicdomain/
     4  */
     6 //-----------------------------------------------------------------------------
     7 var BUGNUMBER = 619283;
     8 var summary =
     9   "ECMAScript built-in methods that immediately throw when |this| is " +
    10   "|undefined| or |null| (due to CheckObjectCoercible, ToObject, or ToString)";
    12 print(BUGNUMBER + ": " + summary);
    14 /**************
    15  * BEGIN TEST *
    16  **************/
    18 // We can't just exhaustively loop over everything because 1) method properties
    19 // might be extensions with special |this| handling, and 2) some methods don't
    20 // *quite* immediately throw a TypeError, first thing, if |this| is |undefined|
    21 // or |null|, or their algorithms are very slightly ambiguous about whether they
    22 // do.  Why?  Ipse-dixitism.  *shrug*
    24 var ClassToMethodMap =
    25   {
    26     Object:  [/* "toString" has special |this| handling */
    27               "toLocaleString", "valueOf", "hasOwnProperty",
    28               /*
    29                * "isPrototypeOf" has special |this| handling already tested in
    30                * ecma_5/Object/isPrototypeOf.js.
    31                */
    32               /*
    33                * "isPrototypeOf" has special |this| handling already tested in
    34                * ecma_5/Object/propertyIsEnumerable.js.
    35                */],
    36     // Function methods often don't ToObject(this) as their very first step,
    37     // and they're already stepwise well-tested such that manual tests here
    38     // would be redundant.
    39     Array:   ["toString", "toLocaleString", "concat", "join", "pop", "push",
    40               "reverse", "shift", "slice", "sort", "splice", "unshift",
    41               "indexOf", "lastIndexOf", "every", "some", "forEach", "map",
    42               "filter", "reduce", "reduceRight"],
    43     String:  ["toString", "valueOf", "charAt", "charCodeAt", "concat",
    44               "indexOf", "lastIndexOf", "localeCompare", "match", "replace",
    45               "search", "slice", "split", "substring", "toLowerCase",
    46               "toLocaleLowerCase", "toUpperCase", "toLocaleUpperCase", "trim",
    47               /*
    48                * "trimLeft" and "trimRight" are non-standard and thus are tested
    49                * in ecma_5/extensions/trim-extensions.js.
    50                */
    51               ],
    52     Boolean: ["toString", "valueOf"],
    53     Number:  ["toString", "toLocaleString", "valueOf",
    54               /*
    55                * toFixed doesn't *immediately* test |this| for number or
    56                * Number-ness, but because the ToInteger(void 0) which arguably
    57                * precedes it in the toFixed algorithm won't throw in this test,
    58                * we don't need to specially test it.
    59                */
    60               "toFixed",
    61               "toExponential", "toPrecision"],
    62     Date:    ["toString", "toDateString", "toTimeString", "toLocaleString",
    63               "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime",
    64               "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth",
    65               "getDate", "getUTCDate", "getDay", "getUTCDay", "getHours",
    66               "getUTCHours", "getMinutes", "getUTCMinutes", "getSeconds",
    67               "getUTCSeconds", "getMilliseconds", "getUTCMilliseconds",
    68               /*
    69                * toFixed doesn't *immediately* test |this| for number or
    70                * Number-ness, but because the TimeClip(ToNumber(void 0)) which
    71                * arguably precedes it in the setTime algorithm won't throw in
    72                * this test, we don't need to specially test it.
    73                */
    74               "setTime",
    75               "getTimezoneOffset", "setMilliseconds", "setUTCMilliseconds",
    76               "setSeconds", "setUTCSeconds", "setMinutes", "setUTCMinutes",
    77               "setHours", "setUTCHours", "setDate", "setUTCDate",  "setMonth",
    78               "setUTCMonth", "setFullYear", "setUTCFullYear", "toUTCString",
    79               "toISOString", "toJSON"],
    80     RegExp:  ["exec", "test", "toString"],
    81     Error:   ["toString"],
    82   };
    84 var badThisValues = [null, undefined];
    86 function testMethod(Class, className, method)
    87 {
    88   var expr;
    90   // Try out explicit this values
    91   for (var i = 0, sz = badThisValues.length; i < sz; i++)
    92   {
    93     var badThis = badThisValues[i];
    95     expr = className + ".prototype." + method + ".call(" + badThis + ")";
    96     try
    97     {
    98       Class.prototype[method].call(badThis);
    99       throw new Error(expr + " didn't throw a TypeError");
   100     }
   101     catch (e)
   102     {
   103       assertEq(e instanceof TypeError, true,
   104                "wrong error for " + expr + ", instead threw " + e);
   105     }
   107     expr = className + ".prototype." + method + ".apply(" + badThis + ")";
   108     try
   109     {
   110       Class.prototype[method].apply(badThis);
   111       throw new Error(expr + " didn't throw a TypeError");
   112     }
   113     catch (e)
   114     {
   115       assertEq(e instanceof TypeError, true,
   116                "wrong error for " + expr + ", instead threw " + e);
   117     }
   118   }
   120   // ..and for good measure..
   122   expr = "(0, " + className + ".prototype." + method + ")()"
   123   try
   124   {
   125     // comma operator to call GetValue() on the method and de-Reference it
   126     (0, Class.prototype[method])();
   127     throw new Error(expr + " didn't throw a TypeError");
   128   }
   129   catch (e)
   130   {
   131     assertEq(e instanceof TypeError, true,
   132              "wrong error for " + expr + ", instead threw " + e);
   133   }
   134 }
   136 for (var className in ClassToMethodMap)
   137 {
   138   var Class = this[className];
   140   var methodNames = ClassToMethodMap[className];
   141   for (var i = 0, sz = methodNames.length; i < sz; i++)
   142   {
   143     var method = methodNames[i];
   144     testMethod(Class, className, method);
   145   }
   146 }
   148 /******************************************************************************/
   150 if (typeof reportCompare === "function")
   151   reportCompare(true, true);
   153 print("All tests passed!");

mercurial