Wed, 31 Dec 2014 06:09:35 +0100
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 var gTestfile = 'function-bind.js';
7 var BUGNUMBER = 429507;
8 var summary = "ES5: Function.prototype.bind";
10 print(BUGNUMBER + ": " + summary);
12 /**************
13 * BEGIN TEST *
14 **************/
16 // ad-hoc testing
18 assertEq(Function.prototype.hasOwnProperty("bind"), true);
20 var bind = Function.prototype.bind;
21 assertEq(bind.length, 1);
24 var strictReturnThis = function() { "use strict"; return this; };
26 assertEq(strictReturnThis.bind(undefined)(), undefined);
27 assertEq(strictReturnThis.bind(null)(), null);
29 var obj = {};
30 assertEq(strictReturnThis.bind(obj)(), obj);
32 assertEq(strictReturnThis.bind(NaN)(), NaN);
34 assertEq(strictReturnThis.bind(true)(), true);
35 assertEq(strictReturnThis.bind(false)(), false);
37 assertEq(strictReturnThis.bind("foopy")(), "foopy");
40 // rigorous, step-by-step testing
42 function expectThrowTypeError(fun)
43 {
44 try
45 {
46 var r = fun();
47 throw new Error("didn't throw TypeError, returned " + r);
48 }
49 catch (e)
50 {
51 assertEq(e instanceof TypeError, true,
52 "didn't throw TypeError, got: " + e);
53 }
54 }
56 /*
57 * 1. Let Target be the this value.
58 * 2. If IsCallable(Target) is false, throw a TypeError exception.
59 */
60 expectThrowTypeError(function() { bind.call(null); });
61 expectThrowTypeError(function() { bind.call(undefined); });
62 expectThrowTypeError(function() { bind.call(NaN); });
63 expectThrowTypeError(function() { bind.call(0); });
64 expectThrowTypeError(function() { bind.call(-0); });
65 expectThrowTypeError(function() { bind.call(17); });
66 expectThrowTypeError(function() { bind.call(42); });
67 expectThrowTypeError(function() { bind.call("foobar"); });
68 expectThrowTypeError(function() { bind.call(true); });
69 expectThrowTypeError(function() { bind.call(false); });
70 expectThrowTypeError(function() { bind.call([]); });
71 expectThrowTypeError(function() { bind.call({}); });
74 /*
75 * 3. Let A be a new (possibly empty) internal list of all of the argument
76 * values provided after thisArg (arg1, arg2 etc), in order.
77 * 4. Let F be a new native ECMAScript object .
78 * 5. Set all the internal methods, except for [[Get]], of F as specified in
79 * 8.12.
80 * 6. Set the [[Get]] internal property of F as specified in 15.3.5.4.
81 * 7. Set the [[TargetFunction]] internal property of F to Target.
82 * 8. Set the [[BoundThis]] internal property of F to the value of thisArg.
83 * 9. Set the [[BoundArgs]] internal property of F to A.
84 */
85 // throughout
88 /* 10. Set the [[Class]] internal property of F to "Function". */
89 var toString = Object.prototype.toString;
90 assertEq(toString.call(function(){}), "[object Function]");
91 assertEq(toString.call(function a(){}), "[object Function]");
92 assertEq(toString.call(function(a){}), "[object Function]");
93 assertEq(toString.call(function a(b){}), "[object Function]");
94 assertEq(toString.call(function(){}.bind()), "[object Function]");
95 assertEq(toString.call(function a(){}.bind()), "[object Function]");
96 assertEq(toString.call(function(a){}.bind()), "[object Function]");
97 assertEq(toString.call(function a(b){}.bind()), "[object Function]");
100 /*
101 * 11. Set the [[Prototype]] internal property of F to the standard built-in
102 * Function prototype object as specified in 15.3.3.1.
103 */
104 assertEq(Object.getPrototypeOf(bind.call(function(){})), Function.prototype);
105 assertEq(Object.getPrototypeOf(bind.call(function a(){})), Function.prototype);
106 assertEq(Object.getPrototypeOf(bind.call(function(a){})), Function.prototype);
107 assertEq(Object.getPrototypeOf(bind.call(function a(b){})), Function.prototype);
110 /*
111 * 12. Set the [[Call]] internal property of F as described in 15.3.4.5.1.
112 */
113 var a = Array.bind(1, 2);
114 assertEq(a().length, 2);
115 assertEq(a(4).length, 2);
116 assertEq(a(4, 8).length, 3);
118 function t() { return this; }
119 var bt = t.bind(t);
120 assertEq(bt(), t);
122 function callee() { return arguments.callee; }
123 var call = callee.bind();
124 assertEq(call(), callee);
125 assertEq(new call(), callee);
128 /*
129 * 13. Set the [[Construct]] internal property of F as described in 15.3.4.5.2.
130 */
131 function Point(x, y)
132 {
133 this.x = x;
134 this.y = y;
135 }
136 var YAxisPoint = Point.bind(null, 0)
138 assertEq(YAxisPoint.hasOwnProperty("prototype"), false);
139 var p = new YAxisPoint(5);
140 assertEq(p.x, 0);
141 assertEq(p.y, 5);
142 assertEq(p instanceof Point, true);
143 assertEq(p instanceof YAxisPoint, true);
144 assertEq(Object.prototype.toString.call(YAxisPoint), "[object Function]");
145 assertEq(YAxisPoint.length, 1);
148 /*
149 * 14. Set the [[HasInstance]] internal property of F as described in
150 * 15.3.4.5.3.
151 */
152 function JoinArguments()
153 {
154 this.args = Array.prototype.join.call(arguments, ", ");
155 }
157 var Join1 = JoinArguments.bind(null, 1);
158 var Join2 = Join1.bind(null, 2);
159 var Join3 = Join2.bind(null, 3);
160 var Join4 = Join3.bind(null, 4);
161 var Join5 = Join4.bind(null, 5);
162 var Join6 = Join5.bind(null, 6);
164 var r = new Join6(7);
165 assertEq(r instanceof Join6, true);
166 assertEq(r instanceof Join5, true);
167 assertEq(r instanceof Join4, true);
168 assertEq(r instanceof Join3, true);
169 assertEq(r instanceof Join2, true);
170 assertEq(r instanceof Join1, true);
171 assertEq(r instanceof JoinArguments, true);
172 assertEq(r.args, "1, 2, 3, 4, 5, 6, 7");
175 /*
176 * 15. If the [[Class]] internal property of Target is "Function", then
177 * a. Let L be the length property of Target minus the length of A.
178 * b. Set the length own property of F to either 0 or L, whichever is larger.
179 * 16. Else set the length own property of F to 0.
180 */
181 function none() { return arguments.length; }
182 assertEq(none.bind(1, 2)(3, 4), 3);
183 assertEq(none.bind(1, 2)(), 1);
184 assertEq(none.bind(1)(2, 3), 2);
185 assertEq(none.bind().length, 0);
186 assertEq(none.bind(null).length, 0);
187 assertEq(none.bind(null, 1).length, 0);
188 assertEq(none.bind(null, 1, 2).length, 0);
190 function one(a) { }
191 assertEq(one.bind().length, 1);
192 assertEq(one.bind(null).length, 1);
193 assertEq(one.bind(null, 1).length, 0);
194 assertEq(one.bind(null, 1, 2).length, 0);
196 // retch
197 var br = Object.create(null, { length: { value: 0 } });
198 try
199 {
200 br = bind.call(/a/g, /a/g, "aaaa");
201 }
202 catch (e) { /* nothing */ }
203 assertEq(br.length, 0);
206 /*
207 * 17. Set the attributes of the length own property of F to the values
208 * specified in 15.3.5.1.
209 */
210 var len1Desc =
211 Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(), "length");
212 assertEq(len1Desc.value, 3);
213 assertEq(len1Desc.writable, false);
214 assertEq(len1Desc.enumerable, false);
215 assertEq(len1Desc.configurable, false);
217 var len2Desc =
218 Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(null, 2), "length");
219 assertEq(len2Desc.value, 2);
220 assertEq(len2Desc.writable, false);
221 assertEq(len2Desc.enumerable, false);
222 assertEq(len2Desc.configurable, false);
225 /*
226 * 18. Set the [[Extensible]] internal property of F to true.
227 */
228 var bound = (function() { }).bind();
230 var isExtensible = Object.isExtensible || function() { return true; };
231 assertEq(isExtensible(bound), true);
233 bound.foo = 17;
234 var fooDesc = Object.getOwnPropertyDescriptor(bound, "foo");
235 assertEq(fooDesc.value, 17);
236 assertEq(fooDesc.writable, true);
237 assertEq(fooDesc.enumerable, true);
238 assertEq(fooDesc.configurable, true);
241 /*
242 * 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
243 * 20. Call the [[DefineOwnProperty]] internal method of F with arguments
244 * "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
245 * [[Enumerable]]: false, [[Configurable]]: false}, and false.
246 * 21. Call the [[DefineOwnProperty]] internal method of F with arguments
247 * "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
248 * [[Enumerable]]: false, [[Configurable]]: false}, and false.
249 */
250 function f() { "use strict"; }
251 var canonicalTTE = Object.getOwnPropertyDescriptor(f, "caller").get;
253 var tte;
255 var boundf = f.bind();
257 var boundfCaller = Object.getOwnPropertyDescriptor(boundf, "caller");
258 assertEq("get" in boundfCaller, true);
259 assertEq("set" in boundfCaller, true);
260 tte = boundfCaller.get;
261 assertEq(tte, canonicalTTE);
262 assertEq(tte, boundfCaller.set);
264 var boundfArguments = Object.getOwnPropertyDescriptor(boundf, "arguments");
265 assertEq("get" in boundfArguments, true);
266 assertEq("set" in boundfArguments, true);
267 tte = boundfArguments.get;
268 assertEq(tte, canonicalTTE);
269 assertEq(tte, boundfArguments.set);
272 /* 22. Return F. */
273 var passim = function p(){}.bind(1);
274 assertEq(typeof passim, "function");
277 /******************************************************************************/
279 if (typeof reportCompare === "function")
280 reportCompare(true, true);
282 print("All tests passed!");