1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/ecma_5/Function/function-bind.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,282 @@ 1.4 +/* 1.5 + * Any copyright is dedicated to the Public Domain. 1.6 + * http://creativecommons.org/licenses/publicdomain/ 1.7 + */ 1.8 + 1.9 +var gTestfile = 'function-bind.js'; 1.10 +var BUGNUMBER = 429507; 1.11 +var summary = "ES5: Function.prototype.bind"; 1.12 + 1.13 +print(BUGNUMBER + ": " + summary); 1.14 + 1.15 +/************** 1.16 + * BEGIN TEST * 1.17 + **************/ 1.18 + 1.19 +// ad-hoc testing 1.20 + 1.21 +assertEq(Function.prototype.hasOwnProperty("bind"), true); 1.22 + 1.23 +var bind = Function.prototype.bind; 1.24 +assertEq(bind.length, 1); 1.25 + 1.26 + 1.27 +var strictReturnThis = function() { "use strict"; return this; }; 1.28 + 1.29 +assertEq(strictReturnThis.bind(undefined)(), undefined); 1.30 +assertEq(strictReturnThis.bind(null)(), null); 1.31 + 1.32 +var obj = {}; 1.33 +assertEq(strictReturnThis.bind(obj)(), obj); 1.34 + 1.35 +assertEq(strictReturnThis.bind(NaN)(), NaN); 1.36 + 1.37 +assertEq(strictReturnThis.bind(true)(), true); 1.38 +assertEq(strictReturnThis.bind(false)(), false); 1.39 + 1.40 +assertEq(strictReturnThis.bind("foopy")(), "foopy"); 1.41 + 1.42 + 1.43 +// rigorous, step-by-step testing 1.44 + 1.45 +function expectThrowTypeError(fun) 1.46 +{ 1.47 + try 1.48 + { 1.49 + var r = fun(); 1.50 + throw new Error("didn't throw TypeError, returned " + r); 1.51 + } 1.52 + catch (e) 1.53 + { 1.54 + assertEq(e instanceof TypeError, true, 1.55 + "didn't throw TypeError, got: " + e); 1.56 + } 1.57 +} 1.58 + 1.59 +/* 1.60 + * 1. Let Target be the this value. 1.61 + * 2. If IsCallable(Target) is false, throw a TypeError exception. 1.62 + */ 1.63 +expectThrowTypeError(function() { bind.call(null); }); 1.64 +expectThrowTypeError(function() { bind.call(undefined); }); 1.65 +expectThrowTypeError(function() { bind.call(NaN); }); 1.66 +expectThrowTypeError(function() { bind.call(0); }); 1.67 +expectThrowTypeError(function() { bind.call(-0); }); 1.68 +expectThrowTypeError(function() { bind.call(17); }); 1.69 +expectThrowTypeError(function() { bind.call(42); }); 1.70 +expectThrowTypeError(function() { bind.call("foobar"); }); 1.71 +expectThrowTypeError(function() { bind.call(true); }); 1.72 +expectThrowTypeError(function() { bind.call(false); }); 1.73 +expectThrowTypeError(function() { bind.call([]); }); 1.74 +expectThrowTypeError(function() { bind.call({}); }); 1.75 + 1.76 + 1.77 +/* 1.78 + * 3. Let A be a new (possibly empty) internal list of all of the argument 1.79 + * values provided after thisArg (arg1, arg2 etc), in order. 1.80 + * 4. Let F be a new native ECMAScript object . 1.81 + * 5. Set all the internal methods, except for [[Get]], of F as specified in 1.82 + * 8.12. 1.83 + * 6. Set the [[Get]] internal property of F as specified in 15.3.5.4. 1.84 + * 7. Set the [[TargetFunction]] internal property of F to Target. 1.85 + * 8. Set the [[BoundThis]] internal property of F to the value of thisArg. 1.86 + * 9. Set the [[BoundArgs]] internal property of F to A. 1.87 + */ 1.88 +// throughout 1.89 + 1.90 + 1.91 +/* 10. Set the [[Class]] internal property of F to "Function". */ 1.92 +var toString = Object.prototype.toString; 1.93 +assertEq(toString.call(function(){}), "[object Function]"); 1.94 +assertEq(toString.call(function a(){}), "[object Function]"); 1.95 +assertEq(toString.call(function(a){}), "[object Function]"); 1.96 +assertEq(toString.call(function a(b){}), "[object Function]"); 1.97 +assertEq(toString.call(function(){}.bind()), "[object Function]"); 1.98 +assertEq(toString.call(function a(){}.bind()), "[object Function]"); 1.99 +assertEq(toString.call(function(a){}.bind()), "[object Function]"); 1.100 +assertEq(toString.call(function a(b){}.bind()), "[object Function]"); 1.101 + 1.102 + 1.103 +/* 1.104 + * 11. Set the [[Prototype]] internal property of F to the standard built-in 1.105 + * Function prototype object as specified in 15.3.3.1. 1.106 + */ 1.107 +assertEq(Object.getPrototypeOf(bind.call(function(){})), Function.prototype); 1.108 +assertEq(Object.getPrototypeOf(bind.call(function a(){})), Function.prototype); 1.109 +assertEq(Object.getPrototypeOf(bind.call(function(a){})), Function.prototype); 1.110 +assertEq(Object.getPrototypeOf(bind.call(function a(b){})), Function.prototype); 1.111 + 1.112 + 1.113 +/* 1.114 + * 12. Set the [[Call]] internal property of F as described in 15.3.4.5.1. 1.115 + */ 1.116 +var a = Array.bind(1, 2); 1.117 +assertEq(a().length, 2); 1.118 +assertEq(a(4).length, 2); 1.119 +assertEq(a(4, 8).length, 3); 1.120 + 1.121 +function t() { return this; } 1.122 +var bt = t.bind(t); 1.123 +assertEq(bt(), t); 1.124 + 1.125 +function callee() { return arguments.callee; } 1.126 +var call = callee.bind(); 1.127 +assertEq(call(), callee); 1.128 +assertEq(new call(), callee); 1.129 + 1.130 + 1.131 +/* 1.132 + * 13. Set the [[Construct]] internal property of F as described in 15.3.4.5.2. 1.133 + */ 1.134 +function Point(x, y) 1.135 +{ 1.136 + this.x = x; 1.137 + this.y = y; 1.138 +} 1.139 +var YAxisPoint = Point.bind(null, 0) 1.140 + 1.141 +assertEq(YAxisPoint.hasOwnProperty("prototype"), false); 1.142 +var p = new YAxisPoint(5); 1.143 +assertEq(p.x, 0); 1.144 +assertEq(p.y, 5); 1.145 +assertEq(p instanceof Point, true); 1.146 +assertEq(p instanceof YAxisPoint, true); 1.147 +assertEq(Object.prototype.toString.call(YAxisPoint), "[object Function]"); 1.148 +assertEq(YAxisPoint.length, 1); 1.149 + 1.150 + 1.151 +/* 1.152 + * 14. Set the [[HasInstance]] internal property of F as described in 1.153 + * 15.3.4.5.3. 1.154 + */ 1.155 +function JoinArguments() 1.156 +{ 1.157 + this.args = Array.prototype.join.call(arguments, ", "); 1.158 +} 1.159 + 1.160 +var Join1 = JoinArguments.bind(null, 1); 1.161 +var Join2 = Join1.bind(null, 2); 1.162 +var Join3 = Join2.bind(null, 3); 1.163 +var Join4 = Join3.bind(null, 4); 1.164 +var Join5 = Join4.bind(null, 5); 1.165 +var Join6 = Join5.bind(null, 6); 1.166 + 1.167 +var r = new Join6(7); 1.168 +assertEq(r instanceof Join6, true); 1.169 +assertEq(r instanceof Join5, true); 1.170 +assertEq(r instanceof Join4, true); 1.171 +assertEq(r instanceof Join3, true); 1.172 +assertEq(r instanceof Join2, true); 1.173 +assertEq(r instanceof Join1, true); 1.174 +assertEq(r instanceof JoinArguments, true); 1.175 +assertEq(r.args, "1, 2, 3, 4, 5, 6, 7"); 1.176 + 1.177 + 1.178 +/* 1.179 + * 15. If the [[Class]] internal property of Target is "Function", then 1.180 + * a. Let L be the length property of Target minus the length of A. 1.181 + * b. Set the length own property of F to either 0 or L, whichever is larger. 1.182 + * 16. Else set the length own property of F to 0. 1.183 + */ 1.184 +function none() { return arguments.length; } 1.185 +assertEq(none.bind(1, 2)(3, 4), 3); 1.186 +assertEq(none.bind(1, 2)(), 1); 1.187 +assertEq(none.bind(1)(2, 3), 2); 1.188 +assertEq(none.bind().length, 0); 1.189 +assertEq(none.bind(null).length, 0); 1.190 +assertEq(none.bind(null, 1).length, 0); 1.191 +assertEq(none.bind(null, 1, 2).length, 0); 1.192 + 1.193 +function one(a) { } 1.194 +assertEq(one.bind().length, 1); 1.195 +assertEq(one.bind(null).length, 1); 1.196 +assertEq(one.bind(null, 1).length, 0); 1.197 +assertEq(one.bind(null, 1, 2).length, 0); 1.198 + 1.199 +// retch 1.200 +var br = Object.create(null, { length: { value: 0 } }); 1.201 +try 1.202 +{ 1.203 + br = bind.call(/a/g, /a/g, "aaaa"); 1.204 +} 1.205 +catch (e) { /* nothing */ } 1.206 +assertEq(br.length, 0); 1.207 + 1.208 + 1.209 +/* 1.210 + * 17. Set the attributes of the length own property of F to the values 1.211 + * specified in 15.3.5.1. 1.212 + */ 1.213 +var len1Desc = 1.214 + Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(), "length"); 1.215 +assertEq(len1Desc.value, 3); 1.216 +assertEq(len1Desc.writable, false); 1.217 +assertEq(len1Desc.enumerable, false); 1.218 +assertEq(len1Desc.configurable, false); 1.219 + 1.220 +var len2Desc = 1.221 + Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(null, 2), "length"); 1.222 +assertEq(len2Desc.value, 2); 1.223 +assertEq(len2Desc.writable, false); 1.224 +assertEq(len2Desc.enumerable, false); 1.225 +assertEq(len2Desc.configurable, false); 1.226 + 1.227 + 1.228 +/* 1.229 + * 18. Set the [[Extensible]] internal property of F to true. 1.230 + */ 1.231 +var bound = (function() { }).bind(); 1.232 + 1.233 +var isExtensible = Object.isExtensible || function() { return true; }; 1.234 +assertEq(isExtensible(bound), true); 1.235 + 1.236 +bound.foo = 17; 1.237 +var fooDesc = Object.getOwnPropertyDescriptor(bound, "foo"); 1.238 +assertEq(fooDesc.value, 17); 1.239 +assertEq(fooDesc.writable, true); 1.240 +assertEq(fooDesc.enumerable, true); 1.241 +assertEq(fooDesc.configurable, true); 1.242 + 1.243 + 1.244 +/* 1.245 + * 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). 1.246 + * 20. Call the [[DefineOwnProperty]] internal method of F with arguments 1.247 + * "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, 1.248 + * [[Enumerable]]: false, [[Configurable]]: false}, and false. 1.249 + * 21. Call the [[DefineOwnProperty]] internal method of F with arguments 1.250 + * "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, 1.251 + * [[Enumerable]]: false, [[Configurable]]: false}, and false. 1.252 + */ 1.253 +function f() { "use strict"; } 1.254 +var canonicalTTE = Object.getOwnPropertyDescriptor(f, "caller").get; 1.255 + 1.256 +var tte; 1.257 + 1.258 +var boundf = f.bind(); 1.259 + 1.260 +var boundfCaller = Object.getOwnPropertyDescriptor(boundf, "caller"); 1.261 +assertEq("get" in boundfCaller, true); 1.262 +assertEq("set" in boundfCaller, true); 1.263 +tte = boundfCaller.get; 1.264 +assertEq(tte, canonicalTTE); 1.265 +assertEq(tte, boundfCaller.set); 1.266 + 1.267 +var boundfArguments = Object.getOwnPropertyDescriptor(boundf, "arguments"); 1.268 +assertEq("get" in boundfArguments, true); 1.269 +assertEq("set" in boundfArguments, true); 1.270 +tte = boundfArguments.get; 1.271 +assertEq(tte, canonicalTTE); 1.272 +assertEq(tte, boundfArguments.set); 1.273 + 1.274 + 1.275 +/* 22. Return F. */ 1.276 +var passim = function p(){}.bind(1); 1.277 +assertEq(typeof passim, "function"); 1.278 + 1.279 + 1.280 +/******************************************************************************/ 1.281 + 1.282 +if (typeof reportCompare === "function") 1.283 + reportCompare(true, true); 1.284 + 1.285 +print("All tests passed!");