Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: test/mjsunit/function-bind.js

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/mjsunit/error-tostring.js ('k') | test/mjsunit/harmony/block-conflicts.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // Tests the Function.prototype.bind (ES 15.3.4.5) method. 28 // Tests the Function.prototype.bind (ES 15.3.4.5) method.
29 29
30 // Simple tests. 30 // Simple tests.
31 function foo(x, y, z) { 31 function foo(x, y, z) {
32 return x + y + z; 32 return [this, arguments.length, x];
33 } 33 }
34 34
35 assertEquals(3, foo.length);
36
35 var f = foo.bind(foo); 37 var f = foo.bind(foo);
36 assertEquals(3, f(1, 1, 1)); 38 assertEquals([foo, 3, 1], f(1, 2, 3));
37 assertEquals(3, f.length); 39 assertEquals(3, f.length);
38 40
39 f = foo.bind(foo, 2); 41 f = foo.bind(foo, 1);
40 assertEquals(4, f(1, 1)); 42 assertEquals([foo, 3, 1], f(2, 3));
41 assertEquals(2, f.length); 43 assertEquals(2, f.length);
42 44
43 f = foo.bind(foo, 2, 2); 45 f = foo.bind(foo, 1, 2);
44 assertEquals(5, f(1)); 46 assertEquals([foo, 3, 1], f(3));
45 assertEquals(1, f.length); 47 assertEquals(1, f.length);
46 48
47 f = foo.bind(foo, 2, 2, 2); 49 f = foo.bind(foo, 1, 2, 3);
48 assertEquals(6, f()); 50 assertEquals([foo, 3, 1], f());
49 assertEquals(0, f.length); 51 assertEquals(0, f.length);
50 52
51 // Test that length works correctly even if more than the actual number 53 // Test that length works correctly even if more than the actual number
52 // of arguments are given when binding. 54 // of arguments are given when binding.
53 f = foo.bind(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9); 55 f = foo.bind(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9);
54 assertEquals(6, f()); 56 assertEquals([foo, 9, 1], f());
55 assertEquals(0, f.length); 57 assertEquals(0, f.length);
56 58
57 // Use a different bound object. 59 // Use a different bound object.
58 var obj = {x: 42, y: 43}; 60 var obj = {x: 42, y: 43};
59 // Values that would normally be in "this" when calling f_bound_this. 61 // Values that would normally be in "this" when calling f_bound_this.
60 var x = 42; 62 var x = 42;
61 var y = 44; 63 var y = 44;
62 64
63 function f_bound_this(z) { 65 function f_bound_this(z) {
64 return z + this.y - this.x; 66 return z + this.y - this.x;
65 } 67 }
66 68
67 assertEquals(3, f_bound_this(1)) 69 assertEquals(3, f_bound_this(1))
68 f = f_bound_this.bind(obj); 70 f = f_bound_this.bind(obj);
69 assertEquals(2, f(1)); 71 assertEquals(2, f(1));
70 assertEquals(1, f.length); 72 assertEquals(1, f.length);
71 73
72 f = f_bound_this.bind(obj, 2); 74 f = f_bound_this.bind(obj, 2);
73 assertEquals(3, f()); 75 assertEquals(3, f());
74 assertEquals(0, f.length); 76 assertEquals(0, f.length);
75 77
76 // Test chained binds. 78 // Test chained binds.
77 79
78 // When only giving the thisArg, any number of binds should have 80 // When only giving the thisArg, any number of binds should have
79 // the same effect. 81 // the same effect.
80 f = foo.bind(foo); 82 f = foo.bind(foo);
81 assertEquals(3, f(1, 1, 1)); 83 assertEquals([foo, 3, 1], f(1, 2, 3));
82 f = foo.bind(foo).bind(foo).bind(foo).bind(foo); 84
83 assertEquals(3, f(1, 1, 1)); 85 var not_foo = {};
86 f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo);
87 assertEquals([foo, 3, 1], f(1, 2, 3));
84 assertEquals(3, f.length); 88 assertEquals(3, f.length);
85 89
86 // Giving bound parameters should work at any place in the chain. 90 // Giving bound parameters should work at any place in the chain.
87 f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo); 91 f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo);
88 assertEquals(3, f(1, 1)); 92 assertEquals([foo, 3, 1], f(2, 3));
89 assertEquals(2, f.length); 93 assertEquals(2, f.length);
90 94
91 f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo); 95 f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo);
92 assertEquals(3, f(1, 1)); 96 assertEquals([foo, 3, 1], f(2, 3));
93 assertEquals(2, f.length); 97 assertEquals(2, f.length);
94 98
95 f = foo.bind(foo).bind(foo).bind(foo,1 ).bind(foo); 99 f = foo.bind(foo).bind(not_foo).bind(not_foo,1 ).bind(not_foo);
96 assertEquals(3, f(1, 1)); 100 assertEquals([foo, 3, 1], f(2, 3));
97 assertEquals(2, f.length); 101 assertEquals(2, f.length);
98 102
99 f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1); 103 f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1);
100 assertEquals(3, f(1, 1)); 104 assertEquals([foo, 3, 1], f(2, 3));
101 assertEquals(2, f.length); 105 assertEquals(2, f.length);
102 106
103 // Several parameters can be given, and given in different bind invokations. 107 // Several parameters can be given, and given in different bind invocations.
104 f = foo.bind(foo, 1, 1).bind(foo).bind(foo).bind(foo); 108 f = foo.bind(foo, 1, 2).bind(not_foo).bind(not_foo).bind(not_foo);
105 assertEquals(3, f(1)); 109 assertEquals([foo, 3, 1], f(3));
106 assertEquals(1, f.length); 110 assertEquals(1, f.length);
107 111
108 f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo); 112 f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
109 assertEquals(3, f(1)); 113 assertEquals([foo, 3, 1], f(1));
110 assertEquals(1, f.length); 114 assertEquals(1, f.length);
111 115
112 f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo); 116 f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
113 assertEquals(3, f(1)); 117 assertEquals([foo, 3, 1], f(3));
114 assertEquals(1, f.length); 118 assertEquals(1, f.length);
115 119
116 f = foo.bind(foo).bind(foo).bind(foo, 1, 1).bind(foo); 120 f = foo.bind(foo).bind(not_foo).bind(not_foo, 1, 2).bind(not_foo);
117 assertEquals(3, f(1)); 121 assertEquals([foo, 3, 1], f(1));
118 assertEquals(1, f.length); 122 assertEquals(1, f.length);
119 123
120 f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1, 1); 124 f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1, 2);
121 assertEquals(3, f(1)); 125 assertEquals([foo, 3, 1], f(3));
122 assertEquals(1, f.length); 126 assertEquals(1, f.length);
123 127
124 f = foo.bind(foo, 1).bind(foo, 1).bind(foo).bind(foo); 128 f = foo.bind(foo, 1).bind(not_foo, 2).bind(not_foo).bind(not_foo);
125 assertEquals(3, f(1)); 129 assertEquals([foo, 3, 1], f(3));
126 assertEquals(1, f.length); 130 assertEquals(1, f.length);
127 131
128 f = foo.bind(foo, 1).bind(foo).bind(foo, 1).bind(foo); 132 f = foo.bind(foo, 1).bind(not_foo).bind(not_foo, 2).bind(not_foo);
129 assertEquals(3, f(1)); 133 assertEquals([foo, 3, 1], f(3));
130 assertEquals(1, f.length); 134 assertEquals(1, f.length);
131 135
132 f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo, 1); 136 f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo, 2);
133 assertEquals(3, f(1)); 137 assertEquals([foo, 3, 1], f(3));
134 assertEquals(1, f.length); 138 assertEquals(1, f.length);
135 139
136 f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo, 1); 140 f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo, 2);
137 assertEquals(3, f(1)); 141 assertEquals([foo, 3, 1], f(3));
138 assertEquals(1, f.length); 142 assertEquals(1, f.length);
139 143
144 // The wrong number of arguments can be given to bound functions too.
145 f = foo.bind(foo);
146 assertEquals(3, f.length);
147 assertEquals([foo, 0, undefined], f());
148 assertEquals([foo, 1, 1], f(1));
149 assertEquals([foo, 2, 1], f(1, 2));
150 assertEquals([foo, 3, 1], f(1, 2, 3));
151 assertEquals([foo, 4, 1], f(1, 2, 3, 4));
152
153 f = foo.bind(foo, 1);
154 assertEquals(2, f.length);
155 assertEquals([foo, 1, 1], f());
156 assertEquals([foo, 2, 1], f(2));
157 assertEquals([foo, 3, 1], f(2, 3));
158 assertEquals([foo, 4, 1], f(2, 3, 4));
159
160 f = foo.bind(foo, 1, 2);
161 assertEquals(1, f.length);
162 assertEquals([foo, 2, 1], f());
163 assertEquals([foo, 3, 1], f(3));
164 assertEquals([foo, 4, 1], f(3, 4));
165
166 f = foo.bind(foo, 1, 2, 3);
167 assertEquals(0, f.length);
168 assertEquals([foo, 3, 1], f());
169 assertEquals([foo, 4, 1], f(4));
170
171 f = foo.bind(foo, 1, 2, 3, 4);
172 assertEquals(0, f.length);
173 assertEquals([foo, 4, 1], f());
174
140 // Test constructor calls. 175 // Test constructor calls.
141 176
142 function bar(x, y, z) { 177 function bar(x, y, z) {
143 this.x = x; 178 this.x = x;
144 this.y = y; 179 this.y = y;
145 this.z = z; 180 this.z = z;
146 } 181 }
147 182
148 f = bar.bind(bar); 183 f = bar.bind(bar);
149 var obj2 = new f(1,2,3); 184 var obj2 = new f(1,2,3);
(...skipping 14 matching lines...) Expand all
164 assertEquals(3, obj2.z); 199 assertEquals(3, obj2.z);
165 200
166 f = bar.bind(bar, 1, 2, 3); 201 f = bar.bind(bar, 1, 2, 3);
167 obj2 = new f(); 202 obj2 = new f();
168 assertEquals(1, obj2.x); 203 assertEquals(1, obj2.x);
169 assertEquals(2, obj2.y); 204 assertEquals(2, obj2.y);
170 assertEquals(3, obj2.z); 205 assertEquals(3, obj2.z);
171 206
172 207
173 // Test bind chains when used as a constructor. 208 // Test bind chains when used as a constructor.
174
175 f = bar.bind(bar, 1).bind(bar, 2).bind(bar, 3); 209 f = bar.bind(bar, 1).bind(bar, 2).bind(bar, 3);
176 obj2 = new f(); 210 obj2 = new f();
177 assertEquals(1, obj2.x); 211 assertEquals(1, obj2.x);
178 assertEquals(2, obj2.y); 212 assertEquals(2, obj2.y);
179 assertEquals(3, obj2.z); 213 assertEquals(3, obj2.z);
180 214
181 // Test instanceof obj2 is bar, not f. 215 // Test obj2 is instanceof both bar and f.
182 assertTrue(obj2 instanceof bar); 216 assertTrue(obj2 instanceof bar);
183 assertFalse(obj2 instanceof f); 217 assertTrue(obj2 instanceof f);
218
219 // This-args are not relevant to instanceof.
220 f = bar.bind(foo.prototype, 1).
221 bind(String.prototype, 2).
222 bind(Function.prototype, 3);
223 var obj3 = new f();
224 assertTrue(obj3 instanceof bar);
225 assertTrue(obj3 instanceof f);
226 assertFalse(obj3 instanceof foo);
227 assertFalse(obj3 instanceof Function);
228 assertFalse(obj3 instanceof String);
229
230 // thisArg is converted to object.
231 f = foo.bind(undefined);
232 assertEquals([this, 0, undefined], f());
233
234 f = foo.bind(null);
235 assertEquals([this, 0, undefined], f());
236
237 f = foo.bind(42);
238 assertEquals([Object(42), 0, undefined], f());
239
240 f = foo.bind("foo");
241 assertEquals([Object("foo"), 0, undefined], f());
242
243 f = foo.bind(true);
244 assertEquals([Object(true), 0, undefined], f());
245
246 // Strict functions don't convert thisArg.
247 function soo(x, y, z) {
248 "use strict";
249 return [this, arguments.length, x];
250 }
251
252 var s = soo.bind(undefined);
253 assertEquals([undefined, 0, undefined], s());
254
255 s = soo.bind(null);
256 assertEquals([null, 0, undefined], s());
257
258 s = soo.bind(42);
259 assertEquals([42, 0, undefined], s());
260
261 s = soo.bind("foo");
262 assertEquals(["foo", 0, undefined], s());
263
264 s = soo.bind(true);
265 assertEquals([true, 0, undefined], s());
266
267 // Test that .arguments and .caller are poisoned according to the ES5 spec.
268
269 // Check that property descriptors are correct (unconfigurable, unenumerable,
270 // and both get and set is the ThrowTypeError function).
271 var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
272 var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
273
274 assertFalse(cdesc.enumerable);
275 assertFalse(cdesc.configurable);
276
277 assertFalse(adesc.enumerable);
278 assertFalse(adesc.configurable);
279
280 assertSame(cdesc.get, cdesc.set);
281 assertSame(cdesc.get, adesc.get);
282 assertSame(cdesc.get, adesc.set);
283
284 assertTrue(cdesc.get instanceof Function);
285 assertEquals(0, cdesc.get.length);
286 assertThrows(cdesc.get, TypeError);
287
288 assertThrows(function() { return f.caller; }, TypeError);
289 assertThrows(function() { f.caller = 42; }, TypeError);
290 assertThrows(function() { return f.arguments; }, TypeError);
291 assertThrows(function() { f.arguments = 42; }, TypeError);
292
293 // Shouldn't throw. Accessing the functions caller must throw if
294 // the caller is strict and the callee isn't. A bound function is built-in,
295 // but not considered strict.
296 (function foo() { return foo.caller; }).bind()();
OLDNEW
« no previous file with comments | « test/mjsunit/error-tostring.js ('k') | test/mjsunit/harmony/block-conflicts.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698