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

Side by Side Diff: test/mjsunit/harmony/array-concat.js

Issue 771483002: Implement ES6 @@isConcatSpreadable (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove default case from IterateElements(), add missing Fixed<Type>Array cases Created 6 years 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
« src/runtime/runtime-array.cc ('K') | « src/runtime/runtime-array.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --harmony-arrays --harmony-classes
6
7 (function testArrayConcatArity() {
8 "use strict";
9 assertEquals(1, Array.prototype.concat.length);
10 })();
11
12
13 (function testArrayConcatNoPrototype() {
14 "use strict";
15 assertEquals(void 0, Array.prototype.concat.prototype);
16 })();
17
18
19 (function testArrayConcatDescriptor() {
20 "use strict";
21 var desc = Object.getOwnPropertyDescriptor(Array.prototype, 'concat');
22 assertEquals(false, desc.enumerable);
23 })();
24
25
26 (function testConcatArrayLike() {
27 "use strict";
28 var obj = {
29 "length": 6,
30 "1": "A",
31 "3": "B",
32 "5": "C"
33 };
34 obj[Symbol.isConcatSpreadable] = true;
35 var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
36 var arr = ["X", "Y", "Z"];
37 assertEquals([void 0, "A", void 0, "B", void 0, "C",
38 { "length": 3, "0": "0", "1": "1", "2": "2" },
39 "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
40 })();
41
42
43 (function testConcatHoleyArray() {
44 "use strict";
45 var arr = [];
46 arr[4] = "Item 4";
47 arr[8] = "Item 8";
48 var arr2 = [".", "!", "?"];
49 assertEquals([void 0, void 0, void 0, void 0, "Item 4", void 0, void 0,
50 void 0, "Item 8", ".", "!", "?"], arr.concat(arr2));
51 })();
52
53
54 (function testIsConcatSpreadableGetterThrows() {
55 "use strict";
56 function MyError() {}
57 var obj = {};
58 Object.defineProperty(obj, Symbol.isConcatSpreadable, {
59 get: function() { throw new MyError(); }
60 });
61
62 assertThrows(function() {
63 [].concat(obj);
64 }, MyError);
65
66 assertThrows(function() {
67 Array.prototype.concat.call(obj, 1, 2, 3);
68 }, MyError);
69 })();
70
71
72 (function testConcatLengthThrows() {
73 "use strict";
74 function MyError() {}
75 var obj = {};
76 obj[Symbol.isConcatSpreadable] = true;
77 Object.defineProperty(obj, "length", {
78 get: function() { throw new MyError(); }
79 });
80
81 assertThrows(function() {
82 [].concat(obj);
83 }, MyError);
84
85 assertThrows(function() {
86 Array.prototype.concat.call(obj, 1, 2, 3);
87 }, MyError);
88 })();
89
90
91 (function testConcatArraySubclass() {
92 "use strict";
93 // TODO(caitp): when concat is called on instances of classes which extend
94 // Array, they should:
95 //
96 // - return an instance of the class, rather than an Array instance (if from
97 // same Realm)
98 // - always treat such classes as concat-spreadable
99 })();
100
101
102 (function testConcatNonArray() {
103 "use strict";
104 class NonArray {
105 constructor() { Array.apply(this, arguments); }
106 };
107
108 var obj = new NonArray(1,2,3);
109 var result = Array.prototype.concat.call(obj, 4, 5, 6);
110 assertEquals(Array, result.constructor);
111 assertEquals([obj,4,5,6], result);
112 assertFalse(result instanceof NonArray);
113 })();
114
115
116 function testConcatTypedArray(type, elems, modulo) {
117 "use strict";
118 var items = new Array(elems);
119 for (var i = 0; i < elems; ++i) {
120 items[i] = modulo === false ? i : elems % modulo;
121 }
122 var ta = new type(items);
Dmitry Lomov (no reviews) 2014/12/11 15:11:29 The reason why you are not hitting UINT8_ELEMENTS
caitp (gmail) 2014/12/11 16:33:09 In order to use Fixed<Type>Array, the length needs
123 assertEquals([ta, ta], [].concat(ta, ta));
124 ta[Symbol.isConcatSpreadable] = true;
125 assertEquals(items, [].concat(ta));
126 }
127
128 (function testConcatSmallTypedArray() {
129 var max = [2^8, 2^16, 2^32, false, false];
130 [
131 Uint8Array,
132 Uint16Array,
133 Uint32Array,
134 Float32Array,
135 Float64Array
136 ].forEach(function(ctor, i) {
137 testConcatTypedArray(ctor, 2, max[i]);
138 });
139 })();
140
141
142 (function testConcatLargeTypedArray() {
143 var max = [2^8, 2^16, 2^32, false, false];
144 [
145 Uint8Array,
146 Uint16Array,
147 Uint32Array,
148 Float32Array,
149 Float64Array
150 ].forEach(function(ctor, i) {
151 testConcatTypedArray(ctor, 4000, max[i]);
152 });
153 })();
154
155
156 (function testConcatStrictArguments() {
157 var args = (function(a, b, c) { "use strict"; return arguments; })(1,2,3);
158 args[Symbol.isConcatSpreadable] = true;
159 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
160 })();
161
162
163 (function testConcatSloppyArguments() {
164 var args = (function(a, b, c) { return arguments; })(1,2,3);
165 args[Symbol.isConcatSpreadable] = true;
166 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
167 })();
168
169
170 (function testConcatSloppyArgumentsWithDupes() {
171 var args = (function(a, a, a) { return arguments; })(1,2,3);
172 args[Symbol.isConcatSpreadable] = true;
173 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
174 })();
175
176
177 (function testConcatSloppyArgumentsThrows() {
178 function MyError() {}
179 var args = (function(a) { return arguments; })(1,2,3);
180 Object.defineProperty(args, 0, {
181 get: function() { throw new MyError(); }
182 });
183 args[Symbol.isConcatSpreadable] = true;
184 assertThrows(function() {
185 return [].concat(args, args);
186 }, MyError);
187 })();
188
189
190 (function testConcatHoleySloppyArguments() {
191 var args = (function(a) { return arguments; })(1,2,3);
192 delete args[1];
193 args[Symbol.isConcatSpreadable] = true;
194 assertEquals([1, void 0, 3, 1, void 0, 3], [].concat(args, args));
195 })();
196
197
198 // ES5 tests
199 (function testArrayConcatES5() {
200 "use strict";
201 var poses;
202 var pos;
203
204 poses = [140, 4000000000];
205 while (pos = poses.shift()) {
206 var a = new Array(pos);
207 var array_proto = [];
208 a.__proto__ = array_proto;
209 assertEquals(pos, a.length);
210 a.push('foo');
211 assertEquals(pos + 1, a.length);
212 var b = ['bar'];
213 var c = a.concat(b);
214 assertEquals(pos + 2, c.length);
215 assertEquals("undefined", typeof(c[pos - 1]));
216 assertEquals("foo", c[pos]);
217 assertEquals("bar", c[pos + 1]);
218
219 // Can we fool the system by putting a number in a string?
220 var onetwofour = "124";
221 a[onetwofour] = 'doo';
222 assertEquals(a[124], 'doo');
223 c = a.concat(b);
224 assertEquals(c[124], 'doo');
225
226 // If we put a number in the prototype, then the spec says it should be
227 // copied on concat.
228 array_proto["123"] = 'baz';
229 assertEquals(a[123], 'baz');
230
231 c = a.concat(b);
232 assertEquals(pos + 2, c.length);
233 assertEquals("baz", c[123]);
234 assertEquals("undefined", typeof(c[pos - 1]));
235 assertEquals("foo", c[pos]);
236 assertEquals("bar", c[pos + 1]);
237
238 // When we take the number off the prototype it disappears from a, but
239 // the concat put it in c itself.
240 array_proto["123"] = undefined;
241 assertEquals("undefined", typeof(a[123]));
242 assertEquals("baz", c[123]);
243
244 // If the element of prototype is shadowed, the element on the instance
245 // should be copied, but not the one on the prototype.
246 array_proto[123] = 'baz';
247 a[123] = 'xyz';
248 assertEquals('xyz', a[123]);
249 c = a.concat(b);
250 assertEquals('xyz', c[123]);
251
252 // Non-numeric properties on the prototype or the array shouldn't get
253 // copied.
254 array_proto.moe = 'joe';
255 a.ben = 'jerry';
256 assertEquals(a["moe"], 'joe');
257 assertEquals(a["ben"], 'jerry');
258 c = a.concat(b);
259 // ben was not copied
260 assertEquals("undefined", typeof(c.ben));
261
262 // When we take moe off the prototype it disappears from all arrays.
263 array_proto.moe = undefined;
264 assertEquals("undefined", typeof(c.moe));
265
266 // Negative indices don't get concated.
267 a[-1] = 'minus1';
268 assertEquals("minus1", a[-1]);
269 assertEquals("undefined", typeof(a[0xffffffff]));
270 c = a.concat(b);
271 assertEquals("undefined", typeof(c[-1]));
272 assertEquals("undefined", typeof(c[0xffffffff]));
273 assertEquals(c.length, a.length + 1);
274 }
275
276 poses = [140, 4000000000];
277 while (pos = poses.shift()) {
278 var a = new Array(pos);
279 assertEquals(pos, a.length);
280 a.push('foo');
281 assertEquals(pos + 1, a.length);
282 var b = ['bar'];
283 var c = a.concat(b);
284 assertEquals(pos + 2, c.length);
285 assertEquals("undefined", typeof(c[pos - 1]));
286 assertEquals("foo", c[pos]);
287 assertEquals("bar", c[pos + 1]);
288
289 // Can we fool the system by putting a number in a string?
290 var onetwofour = "124";
291 a[onetwofour] = 'doo';
292 assertEquals(a[124], 'doo');
293 c = a.concat(b);
294 assertEquals(c[124], 'doo');
295
296 // If we put a number in the prototype, then the spec says it should be
297 // copied on concat.
298 Array.prototype["123"] = 'baz';
299 assertEquals(a[123], 'baz');
300
301 c = a.concat(b);
302 assertEquals(pos + 2, c.length);
303 assertEquals("baz", c[123]);
304 assertEquals("undefined", typeof(c[pos - 1]));
305 assertEquals("foo", c[pos]);
306 assertEquals("bar", c[pos + 1]);
307
308 // When we take the number off the prototype it disappears from a, but
309 // the concat put it in c itself.
310 Array.prototype["123"] = undefined;
311 assertEquals("undefined", typeof(a[123]));
312 assertEquals("baz", c[123]);
313
314 // If the element of prototype is shadowed, the element on the instance
315 // should be copied, but not the one on the prototype.
316 Array.prototype[123] = 'baz';
317 a[123] = 'xyz';
318 assertEquals('xyz', a[123]);
319 c = a.concat(b);
320 assertEquals('xyz', c[123]);
321
322 // Non-numeric properties on the prototype or the array shouldn't get
323 // copied.
324 Array.prototype.moe = 'joe';
325 a.ben = 'jerry';
326 assertEquals(a["moe"], 'joe');
327 assertEquals(a["ben"], 'jerry');
328 c = a.concat(b);
329 // ben was not copied
330 assertEquals("undefined", typeof(c.ben));
331 // moe was not copied, but we can see it through the prototype
332 assertEquals("joe", c.moe);
333
334 // When we take moe off the prototype it disappears from all arrays.
335 Array.prototype.moe = undefined;
336 assertEquals("undefined", typeof(c.moe));
337
338 // Negative indices don't get concated.
339 a[-1] = 'minus1';
340 assertEquals("minus1", a[-1]);
341 assertEquals("undefined", typeof(a[0xffffffff]));
342 c = a.concat(b);
343 assertEquals("undefined", typeof(c[-1]));
344 assertEquals("undefined", typeof(c[0xffffffff]));
345 assertEquals(c.length, a.length + 1);
346
347 }
348
349 a = [];
350 c = a.concat('Hello');
351 assertEquals(1, c.length);
352 assertEquals("Hello", c[0]);
353 assertEquals("Hello", c.toString());
354
355 // Check that concat preserves holes.
356 var holey = [void 0,'a',,'c'].concat(['d',,'f',[0,,2],void 0])
357 assertEquals(9, holey.length); // hole in embedded array is ignored
358 for (var i = 0; i < holey.length; i++) {
359 if (i == 2 || i == 5) {
360 assertFalse(i in holey);
361 } else {
362 assertTrue(i in holey);
363 }
364 }
365
366 // Polluted prototype from prior tests.
367 delete Array.prototype[123];
368
369 // Check that concat reads getters in the correct order.
370 var arr1 = [,2];
371 var arr2 = [1,3];
372 var r1 = [].concat(arr1, arr2); // [,2,1,3]
373 assertEquals([,2,1,3], r1);
374
375 // Make first array change length of second array.
376 Object.defineProperty(arr1, 0, {get: function() {
377 arr2.push("X");
378 return undefined;
379 }, configurable: true})
380 var r2 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
381 assertEquals([undefined,2,1,3,"X"], r2);
382
383 // Make first array change length of second array massively.
384 arr2.length = 2;
385 Object.defineProperty(arr1, 0, {get: function() {
386 arr2[500000] = "X";
387 return undefined;
388 }, configurable: true})
389 var r3 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
390 var expected = [undefined,2,1,3];
391 expected[500000 + 2] = "X";
392
393 assertEquals(expected, r3);
394
395 var arr3 = [];
396 var trace = [];
397 var expectedTrace = []
398 function mkGetter(i) { return function() { trace.push(i); }; }
399 arr3.length = 10000;
400 for (var i = 0; i < 100; i++) {
401 Object.defineProperty(arr3, i * i, {get: mkGetter(i)});
402 expectedTrace[i] = i;
403 expectedTrace[100 + i] = i;
404 }
405 var r4 = [0].concat(arr3, arr3);
406 assertEquals(1 + arr3.length * 2, r4.length);
407 assertEquals(expectedTrace, trace);
408 })();
OLDNEW
« src/runtime/runtime-array.cc ('K') | « src/runtime/runtime-array.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698