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.

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

mercurial