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

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

Issue 1667453002: Remove flags for ES2015 features shipped in M48 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Mark failing ignition/arm64 test as flaky Created 4 years, 10 months 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
« no previous file with comments | « test/mjsunit/es6/regexp-tolength.js ('k') | test/mjsunit/harmony/block-for-sloppy.js » ('j') | 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-concat-spreadable --harmony-proxies --harmony-reflect
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 testConcatArrayLikeStringLength() {
44 "use strict";
45 var obj = {
46 "length": "6",
47 "1": "A",
48 "3": "B",
49 "5": "C"
50 };
51 obj[Symbol.isConcatSpreadable] = true;
52 var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
53 var arr = ["X", "Y", "Z"];
54 assertEquals([void 0, "A", void 0, "B", void 0, "C",
55 { "length": 3, "0": "0", "1": "1", "2": "2" },
56 "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
57 })();
58
59
60 (function testConcatArrayLikeNegativeLength() {
61 "use strict";
62 var obj = {
63 "length": -6,
64 "1": "A",
65 "3": "B",
66 "5": "C"
67 };
68 obj[Symbol.isConcatSpreadable] = true;
69 assertEquals([], [].concat(obj));
70 obj.length = -6.7;
71 assertEquals([], [].concat(obj));
72 obj.length = "-6";
73 assertEquals([], [].concat(obj));
74 })();
75
76
77 (function testConcatArrayLikeToLengthThrows() {
78 "use strict";
79 var obj = {
80 "length": {valueOf: null, toString: null},
81 "1": "A",
82 "3": "B",
83 "5": "C"
84 };
85 obj[Symbol.isConcatSpreadable] = true;
86 var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
87 var arr = ["X", "Y", "Z"];
88 assertThrows(function() {
89 Array.prototype.concat.call(obj, obj2, arr);
90 }, TypeError);
91 })();
92
93
94 (function testConcatArrayLikePrimitiveNonNumberLength() {
95 "use strict";
96 var obj = {
97 "1": "A",
98 "3": "B",
99 "5": "C"
100 };
101 obj[Symbol.isConcatSpreadable] = true;
102 obj.length = {toString: function() { return "SIX"; }, valueOf: null };
103 assertEquals([], [].concat(obj));
104 obj.length = {toString: null, valueOf: function() { return "SIX"; } };
105 assertEquals([], [].concat(obj));
106 })();
107
108
109 (function testConcatArrayLikeLengthToStringThrows() {
110 "use strict";
111 function MyError() {}
112 var obj = {
113 "length": { toString: function() {
114 throw new MyError();
115 }, valueOf: null
116 },
117 "1": "A",
118 "3": "B",
119 "5": "C"
120 };
121 obj[Symbol.isConcatSpreadable] = true;
122 assertThrows(function() {
123 [].concat(obj);
124 }, MyError);
125 })();
126
127
128 (function testConcatArrayLikeLengthValueOfThrows() {
129 "use strict";
130 function MyError() {}
131 var obj = {
132 "length": { valueOf: function() {
133 throw new MyError();
134 }, toString: null
135 },
136 "1": "A",
137 "3": "B",
138 "5": "C"
139 };
140 obj[Symbol.isConcatSpreadable] = true;
141 assertThrows(function() {
142 [].concat(obj);
143 }, MyError);
144 })();
145
146
147 (function testConcatHoleyArray() {
148 "use strict";
149 var arr = [];
150 arr[4] = "Item 4";
151 arr[8] = "Item 8";
152 var arr2 = [".", "!", "?"];
153 assertEquals([void 0, void 0, void 0, void 0, "Item 4", void 0, void 0,
154 void 0, "Item 8", ".", "!", "?"], arr.concat(arr2));
155 })();
156
157
158 (function testIsConcatSpreadableGetterThrows() {
159 "use strict";
160 function MyError() {}
161 var obj = {};
162 Object.defineProperty(obj, Symbol.isConcatSpreadable, {
163 get: function() { throw new MyError(); }
164 });
165
166 assertThrows(function() {
167 [].concat(obj);
168 }, MyError);
169
170 assertThrows(function() {
171 Array.prototype.concat.call(obj, 1, 2, 3);
172 }, MyError);
173 })();
174
175
176 (function testConcatLengthThrows() {
177 "use strict";
178 function MyError() {}
179 var obj = {};
180 obj[Symbol.isConcatSpreadable] = true;
181 Object.defineProperty(obj, "length", {
182 get: function() { throw new MyError(); }
183 });
184
185 assertThrows(function() {
186 [].concat(obj);
187 }, MyError);
188
189 assertThrows(function() {
190 Array.prototype.concat.call(obj, 1, 2, 3);
191 }, MyError);
192 })();
193
194
195 (function testConcatArraySubclass() {
196 "use strict";
197 // If @@isConcatSpreadable is not used, the value of IsArray(O)
198 // is used to determine the spreadable property.
199 class A extends Array {}
200 var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
201 assertEquals(9, obj.length);
202 for (var i = 0; i < obj.length; ++i) {
203 assertEquals(i + 1, obj[i]);
204 }
205
206 // TODO(caitp): when concat is called on instances of classes which extend
207 // Array, they should:
208 //
209 // - return an instance of the class, rather than an Array instance (if from
210 // same Realm)
211 // - always treat such classes as concat-spreadable
212 })();
213
214
215 (function testConcatArraySubclassOptOut() {
216 "use strict";
217 class A extends Array {
218 get [Symbol.isConcatSpreadable]() { return false; }
219 }
220 var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
221 assertEquals(3, obj.length);
222 assertEquals(3, obj[0].length);
223 assertEquals(3, obj[1].length);
224 assertEquals(3, obj[2].length);
225 })();
226
227
228 (function testConcatNonArray() {
229 "use strict";
230 class NonArray {
231 constructor() { Array.apply(this, arguments); }
232 };
233
234 var obj = new NonArray(1,2,3);
235 var result = Array.prototype.concat.call(obj, 4, 5, 6);
236 assertEquals(Array, result.constructor);
237 assertEquals([obj,4,5,6], result);
238 assertFalse(result instanceof NonArray);
239 })();
240
241
242 function testConcatTypedArray(type, elems, modulo) {
243 "use strict";
244 var items = new Array(elems);
245 var ta_by_len = new type(elems);
246 for (var i = 0; i < elems; ++i) {
247 ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
248 }
249 var ta = new type(items);
250 assertEquals([ta, ta], [].concat(ta, ta));
251 ta[Symbol.isConcatSpreadable] = true;
252 assertEquals(items, [].concat(ta));
253
254 assertEquals([ta_by_len, ta_by_len], [].concat(ta_by_len, ta_by_len));
255 ta_by_len[Symbol.isConcatSpreadable] = true;
256 assertEquals(items, [].concat(ta_by_len));
257
258 // TypedArray with fake `length`.
259 ta = new type(1);
260 var defValue = ta[0];
261 var expected = new Array(4000);
262 expected[0] = defValue;
263
264 Object.defineProperty(ta, "length", { value: 4000 });
265 ta[Symbol.isConcatSpreadable] = true;
266 assertEquals(expected, [].concat(ta));
267 }
268
269 (function testConcatSmallTypedArray() {
270 var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
271 [
272 Uint8Array,
273 Uint16Array,
274 Uint32Array,
275 Float32Array,
276 Float64Array
277 ].forEach(function(ctor, i) {
278 testConcatTypedArray(ctor, 1, max[i]);
279 });
280 })();
281
282
283 (function testConcatLargeTypedArray() {
284 var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
285 [
286 Uint8Array,
287 Uint16Array,
288 Uint32Array,
289 Float32Array,
290 Float64Array
291 ].forEach(function(ctor, i) {
292 testConcatTypedArray(ctor, 4000, max[i]);
293 });
294 })();
295
296
297 (function testConcatStrictArguments() {
298 var args = (function(a, b, c) { "use strict"; return arguments; })(1,2,3);
299 args[Symbol.isConcatSpreadable] = true;
300 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
301
302 Object.defineProperty(args, "length", { value: 6 });
303 assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
304 })();
305
306
307 (function testConcatSloppyArguments() {
308 var args = (function(a, b, c) { return arguments; })(1,2,3);
309 args[Symbol.isConcatSpreadable] = true;
310 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
311
312 Object.defineProperty(args, "length", { value: 6 });
313 assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
314 })();
315
316
317 (function testConcatSloppyArgumentsWithDupes() {
318 var args = (function(a, a, a) { return arguments; })(1,2,3);
319 args[Symbol.isConcatSpreadable] = true;
320 assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
321
322 Object.defineProperty(args, "length", { value: 6 });
323 assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
324 })();
325
326
327 (function testConcatSloppyArgumentsThrows() {
328 function MyError() {}
329 var args = (function(a) { return arguments; })(1,2,3);
330 Object.defineProperty(args, 0, {
331 get: function() { throw new MyError(); }
332 });
333 args[Symbol.isConcatSpreadable] = true;
334 assertThrows(function() {
335 return [].concat(args, args);
336 }, MyError);
337 })();
338
339
340 (function testConcatHoleySloppyArguments() {
341 var args = (function(a) { return arguments; })(1,2,3);
342 delete args[1];
343 args[Symbol.isConcatSpreadable] = true;
344 assertEquals([1, void 0, 3, 1, void 0, 3], [].concat(args, args));
345 })();
346
347
348 (function testConcatSpreadableStringWrapper() {
349 "use strict";
350 var str1 = new String("yuck\uD83D\uDCA9")
351 // String wrapper objects are not concat-spreadable by default
352 assertEquals([str1], [].concat(str1));
353
354 // String wrapper objects may be individually concat-spreadable
355 str1[Symbol.isConcatSpreadable] = true;
356 assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
357 [].concat(str1));
358
359 String.prototype[Symbol.isConcatSpreadable] = true;
360 // String wrapper objects may be concat-spreadable
361 assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
362 [].concat(new String("yuck\uD83D\uDCA9")));
363
364 // String values are never concat-spreadable
365 assertEquals(["yuck\uD83D\uDCA9"], [].concat("yuck\uD83D\uDCA9"));
366 delete String.prototype[Symbol.isConcatSpreadable];
367 })();
368
369
370 (function testConcatSpreadableBooleanWrapper() {
371 "use strict";
372 var bool = new Boolean(true)
373 // Boolean wrapper objects are not concat-spreadable by default
374 assertEquals([bool], [].concat(bool));
375
376 // Boolean wrapper objects may be individually concat-spreadable
377 bool[Symbol.isConcatSpreadable] = true;
378 bool.length = 3;
379 bool[0] = 1, bool[1] = 2, bool[2] = 3;
380 assertEquals([1, 2, 3], [].concat(bool));
381
382 Boolean.prototype[Symbol.isConcatSpreadable] = true;
383 // Boolean wrapper objects may be concat-spreadable
384 assertEquals([], [].concat(new Boolean(true)));
385 Boolean.prototype[0] = 1;
386 Boolean.prototype[1] = 2;
387 Boolean.prototype[2] = 3;
388 Boolean.prototype.length = 3;
389 assertEquals([1,2,3], [].concat(new Boolean(true)));
390
391 // Boolean values are never concat-spreadable
392 assertEquals([true], [].concat(true));
393 delete Boolean.prototype[Symbol.isConcatSpreadable];
394 delete Boolean.prototype[0];
395 delete Boolean.prototype[1];
396 delete Boolean.prototype[2];
397 delete Boolean.prototype.length;
398 })();
399
400
401 (function testConcatSpreadableNumberWrapper() {
402 "use strict";
403 var num = new Number(true)
404 // Number wrapper objects are not concat-spreadable by default
405 assertEquals([num], [].concat(num));
406
407 // Number wrapper objects may be individually concat-spreadable
408 num[Symbol.isConcatSpreadable] = true;
409 num.length = 3;
410 num[0] = 1, num[1] = 2, num[2] = 3;
411 assertEquals([1, 2, 3], [].concat(num));
412
413 Number.prototype[Symbol.isConcatSpreadable] = true;
414 // Number wrapper objects may be concat-spreadable
415 assertEquals([], [].concat(new Number(123)));
416 Number.prototype[0] = 1;
417 Number.prototype[1] = 2;
418 Number.prototype[2] = 3;
419 Number.prototype.length = 3;
420 assertEquals([1,2,3], [].concat(new Number(123)));
421
422 // Number values are never concat-spreadable
423 assertEquals([true], [].concat(true));
424 delete Number.prototype[Symbol.isConcatSpreadable];
425 delete Number.prototype[0];
426 delete Number.prototype[1];
427 delete Number.prototype[2];
428 delete Number.prototype.length;
429 })();
430
431
432 (function testConcatSpreadableFunction() {
433 "use strict";
434 var fn = function(a, b, c) {}
435 // Functions are not concat-spreadable by default
436 assertEquals([fn], [].concat(fn));
437
438 // Functions may be individually concat-spreadable
439 fn[Symbol.isConcatSpreadable] = true;
440 fn[0] = 1, fn[1] = 2, fn[2] = 3;
441 assertEquals([1, 2, 3], [].concat(fn));
442
443 Function.prototype[Symbol.isConcatSpreadable] = true;
444 // Functions may be concat-spreadable
445 assertEquals([void 0, void 0, void 0], [].concat(function(a,b,c) {}));
446 Function.prototype[0] = 1;
447 Function.prototype[1] = 2;
448 Function.prototype[2] = 3;
449 assertEquals([1,2,3], [].concat(function(a, b, c) {}));
450
451 delete Function.prototype[Symbol.isConcatSpreadable];
452 delete Function.prototype[0];
453 delete Function.prototype[1];
454 delete Function.prototype[2];
455 })();
456
457
458 (function testConcatSpreadableRegExp() {
459 "use strict";
460 var re = /abc/;
461 // RegExps are not concat-spreadable by default
462 assertEquals([re], [].concat(re));
463
464 // RegExps may be individually concat-spreadable
465 re[Symbol.isConcatSpreadable] = true;
466 re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;
467 assertEquals([1, 2, 3], [].concat(re));
468
469 // RegExps may be concat-spreadable
470 RegExp.prototype[Symbol.isConcatSpreadable] = true;
471 RegExp.prototype.length = 3;
472
473 assertEquals([void 0, void 0, void 0], [].concat(/abc/));
474 RegExp.prototype[0] = 1;
475 RegExp.prototype[1] = 2;
476 RegExp.prototype[2] = 3;
477 assertEquals([1,2,3], [].concat(/abc/));
478
479 delete RegExp.prototype[Symbol.isConcatSpreadable];
480 delete RegExp.prototype[0];
481 delete RegExp.prototype[1];
482 delete RegExp.prototype[2];
483 delete RegExp.prototype.length;
484 })();
485
486
487 (function testArrayConcatSpreadableSparseObject() {
488 "use strict";
489 var obj = { length: 5 };
490 obj[Symbol.isConcatSpreadable] = true;
491 assertEquals([void 0, void 0, void 0, void 0, void 0], [].concat(obj));
492
493 obj.length = 4000;
494 assertEquals(new Array(4000), [].concat(obj));
495 })();
496
497
498 // ES5 tests
499 (function testArrayConcatES5() {
500 "use strict";
501 var poses;
502 var pos;
503
504 poses = [140, 4000000000];
505 while (pos = poses.shift()) {
506 var a = new Array(pos);
507 var array_proto = [];
508 a.__proto__ = array_proto;
509 assertEquals(pos, a.length);
510 a.push('foo');
511 assertEquals(pos + 1, a.length);
512 var b = ['bar'];
513 var c = a.concat(b);
514 assertEquals(pos + 2, c.length);
515 assertEquals("undefined", typeof(c[pos - 1]));
516 assertEquals("foo", c[pos]);
517 assertEquals("bar", c[pos + 1]);
518
519 // Can we fool the system by putting a number in a string?
520 var onetwofour = "124";
521 a[onetwofour] = 'doo';
522 assertEquals(a[124], 'doo');
523 c = a.concat(b);
524 assertEquals(c[124], 'doo');
525
526 // If we put a number in the prototype, then the spec says it should be
527 // copied on concat.
528 array_proto["123"] = 'baz';
529 assertEquals(a[123], 'baz');
530
531 c = a.concat(b);
532 assertEquals(pos + 2, c.length);
533 assertEquals("baz", c[123]);
534 assertEquals("undefined", typeof(c[pos - 1]));
535 assertEquals("foo", c[pos]);
536 assertEquals("bar", c[pos + 1]);
537
538 // When we take the number off the prototype it disappears from a, but
539 // the concat put it in c itself.
540 array_proto["123"] = undefined;
541 assertEquals("undefined", typeof(a[123]));
542 assertEquals("baz", c[123]);
543
544 // If the element of prototype is shadowed, the element on the instance
545 // should be copied, but not the one on the prototype.
546 array_proto[123] = 'baz';
547 a[123] = 'xyz';
548 assertEquals('xyz', a[123]);
549 c = a.concat(b);
550 assertEquals('xyz', c[123]);
551
552 // Non-numeric properties on the prototype or the array shouldn't get
553 // copied.
554 array_proto.moe = 'joe';
555 a.ben = 'jerry';
556 assertEquals(a["moe"], 'joe');
557 assertEquals(a["ben"], 'jerry');
558 c = a.concat(b);
559 // ben was not copied
560 assertEquals("undefined", typeof(c.ben));
561
562 // When we take moe off the prototype it disappears from all arrays.
563 array_proto.moe = undefined;
564 assertEquals("undefined", typeof(c.moe));
565
566 // Negative indices don't get concated.
567 a[-1] = 'minus1';
568 assertEquals("minus1", a[-1]);
569 assertEquals("undefined", typeof(a[0xffffffff]));
570 c = a.concat(b);
571 assertEquals("undefined", typeof(c[-1]));
572 assertEquals("undefined", typeof(c[0xffffffff]));
573 assertEquals(c.length, a.length + 1);
574 }
575
576 poses = [140, 4000000000];
577 while (pos = poses.shift()) {
578 var a = new Array(pos);
579 assertEquals(pos, a.length);
580 a.push('foo');
581 assertEquals(pos + 1, a.length);
582 var b = ['bar'];
583 var c = a.concat(b);
584 assertEquals(pos + 2, c.length);
585 assertEquals("undefined", typeof(c[pos - 1]));
586 assertEquals("foo", c[pos]);
587 assertEquals("bar", c[pos + 1]);
588
589 // Can we fool the system by putting a number in a string?
590 var onetwofour = "124";
591 a[onetwofour] = 'doo';
592 assertEquals(a[124], 'doo');
593 c = a.concat(b);
594 assertEquals(c[124], 'doo');
595
596 // If we put a number in the prototype, then the spec says it should be
597 // copied on concat.
598 Array.prototype["123"] = 'baz';
599 assertEquals(a[123], 'baz');
600
601 c = a.concat(b);
602 assertEquals(pos + 2, c.length);
603 assertEquals("baz", c[123]);
604 assertEquals("undefined", typeof(c[pos - 1]));
605 assertEquals("foo", c[pos]);
606 assertEquals("bar", c[pos + 1]);
607
608 // When we take the number off the prototype it disappears from a, but
609 // the concat put it in c itself.
610 Array.prototype["123"] = undefined;
611 assertEquals("undefined", typeof(a[123]));
612 assertEquals("baz", c[123]);
613
614 // If the element of prototype is shadowed, the element on the instance
615 // should be copied, but not the one on the prototype.
616 Array.prototype[123] = 'baz';
617 a[123] = 'xyz';
618 assertEquals('xyz', a[123]);
619 c = a.concat(b);
620 assertEquals('xyz', c[123]);
621
622 // Non-numeric properties on the prototype or the array shouldn't get
623 // copied.
624 Array.prototype.moe = 'joe';
625 a.ben = 'jerry';
626 assertEquals(a["moe"], 'joe');
627 assertEquals(a["ben"], 'jerry');
628 c = a.concat(b);
629 // ben was not copied
630 assertEquals("undefined", typeof(c.ben));
631 // moe was not copied, but we can see it through the prototype
632 assertEquals("joe", c.moe);
633
634 // When we take moe off the prototype it disappears from all arrays.
635 Array.prototype.moe = undefined;
636 assertEquals("undefined", typeof(c.moe));
637
638 // Negative indices don't get concated.
639 a[-1] = 'minus1';
640 assertEquals("minus1", a[-1]);
641 assertEquals("undefined", typeof(a[0xffffffff]));
642 c = a.concat(b);
643 assertEquals("undefined", typeof(c[-1]));
644 assertEquals("undefined", typeof(c[0xffffffff]));
645 assertEquals(c.length, a.length + 1);
646
647 }
648
649 a = [];
650 c = a.concat('Hello');
651 assertEquals(1, c.length);
652 assertEquals("Hello", c[0]);
653 assertEquals("Hello", c.toString());
654
655 // Check that concat preserves holes.
656 var holey = [void 0,'a',,'c'].concat(['d',,'f',[0,,2],void 0])
657 assertEquals(9, holey.length); // hole in embedded array is ignored
658 for (var i = 0; i < holey.length; i++) {
659 if (i == 2 || i == 5) {
660 assertFalse(i in holey);
661 } else {
662 assertTrue(i in holey);
663 }
664 }
665
666 // Polluted prototype from prior tests.
667 delete Array.prototype[123];
668
669 // Check that concat reads getters in the correct order.
670 var arr1 = [,2];
671 var arr2 = [1,3];
672 var r1 = [].concat(arr1, arr2); // [,2,1,3]
673 assertEquals([,2,1,3], r1);
674
675 // Make first array change length of second array.
676 Object.defineProperty(arr1, 0, {get: function() {
677 arr2.push("X");
678 return undefined;
679 }, configurable: true})
680 var r2 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
681 assertEquals([undefined,2,1,3,"X"], r2);
682
683 // Make first array change length of second array massively.
684 arr2.length = 2;
685 Object.defineProperty(arr1, 0, {get: function() {
686 arr2[500000] = "X";
687 return undefined;
688 }, configurable: true})
689 var r3 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
690 var expected = [undefined,2,1,3];
691 expected[500000 + 2] = "X";
692
693 assertEquals(expected, r3);
694
695 var arr3 = [];
696 var trace = [];
697 var expectedTrace = []
698 function mkGetter(i) { return function() { trace.push(i); }; }
699 arr3.length = 10000;
700 for (var i = 0; i < 100; i++) {
701 Object.defineProperty(arr3, i * i, {get: mkGetter(i)});
702 expectedTrace[i] = i;
703 expectedTrace[100 + i] = i;
704 }
705 var r4 = [0].concat(arr3, arr3);
706 assertEquals(1 + arr3.length * 2, r4.length);
707 assertEquals(expectedTrace, trace);
708
709 // Clean up.
710 delete Array.prototype[123];
711 delete Array.prototype["123"];
712 delete Array.prototype["moe"];
713 })();
714
715
716
717
718 ////////////////////////////////////////////////////////////////////////////////
719 // Tests with proxies
720
721 // Note: concat does not currently support species so there is no difference
722 // between [].concat(foo) and Array.prototype.concat.apply(foo).
723
724
725 var log = [];
726 var logger = {};
727 var handler = new Proxy({}, logger);
728
729 logger.get = function(t, trap, r) {
730 return function(...args) {
731 log.push([trap, ...args]);
732 return Reflect[trap](...args);
733 }
734 };
735
736
737 (function testUnspreadableNonArrayLikeProxy() {
738 var target = {0: "a", 1: "b"};
739 var obj = new Proxy(target, handler);
740
741 log.length = 0;
742 assertEquals([obj], [].concat(obj));
743 assertEquals(1, log.length);
744 for (var i in log) assertSame(target, log[i][1]);
745 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
746
747 log.length = 0;
748 assertEquals([obj], Array.prototype.concat.apply(obj));
749 assertEquals(1, log.length);
750 for (var i in log) assertSame(target, log[i][1]);
751 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
752 })();
753
754
755 (function testSpreadableNonArrayLikeProxy() {
756 var target = {0: "a", 1: "b", [Symbol.isConcatSpreadable]: "truish"};
757 var obj = new Proxy(target, handler);
758
759 log.length = 0;
760 assertEquals([], [].concat(obj));
761 assertEquals(2, log.length);
762 for (var i in log) assertSame(target, log[i][1]);
763 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
764 assertEquals(["get", target, "length", obj], log[1]);
765
766 log.length = 0;
767 assertEquals([], Array.prototype.concat.apply(obj));
768 assertEquals(2, log.length);
769 for (var i in log) assertSame(target, log[i][1]);
770 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
771 assertEquals(["get", target, "length", obj], log[1]);
772
773 target.length = 3;
774
775 log.length = 0;
776 assertEquals(["a", "b", undefined], [].concat(obj));
777 assertEquals(7, log.length);
778 for (var i in log) assertSame(target, log[i][1]);
779 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
780 assertEquals(["get", target, "length", obj], log[1]);
781 assertEquals(["has", target, "0"], log[2]);
782 assertEquals(["get", target, "0", obj], log[3]);
783 assertEquals(["has", target, "1"], log[4]);
784 assertEquals(["get", target, "1", obj], log[5]);
785 assertEquals(["has", target, "2"], log[6]);
786
787 log.length = 0;
788 assertEquals(["a", "b", undefined], Array.prototype.concat.apply(obj));
789 assertEquals(7, log.length);
790 for (var i in log) assertSame(target, log[i][1]);
791 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
792 assertEquals(["get", target, "length", obj], log[1]);
793 assertEquals(["has", target, "0"], log[2]);
794 assertEquals(["get", target, "0", obj], log[3]);
795 assertEquals(["has", target, "1"], log[4]);
796 assertEquals(["get", target, "1", obj], log[5]);
797 assertEquals(["has", target, "2"], log[6]);
798 })();
799
800
801 (function testUnspreadableArrayLikeProxy() {
802 var target = ["a", "b"];
803 target[Symbol.isConcatSpreadable] = "";
804 var obj = new Proxy(target, handler);
805
806 log.length = 0;
807 assertEquals([obj], [].concat(obj));
808 assertEquals(1, log.length);
809 for (var i in log) assertSame(target, log[i][1]);
810 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
811
812 log.length = 0;
813 assertEquals([obj], Array.prototype.concat.apply(obj));
814 assertEquals(1, log.length);
815 for (var i in log) assertSame(target, log[i][1]);
816 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
817 })();
818
819
820 (function testSpreadableArrayLikeProxy() {
821 var target = ["a", "b"];
822 target[Symbol.isConcatSpreadable] = undefined;
823 var obj = new Proxy(target, handler);
824
825 log.length = 0;
826 assertEquals(["a", "b"], [].concat(obj));
827 assertEquals(6, log.length);
828 for (var i in log) assertSame(target, log[i][1]);
829 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
830 assertEquals(["get", target, "length", obj], log[1]);
831 assertEquals(["has", target, "0"], log[2]);
832 assertEquals(["get", target, "0", obj], log[3]);
833 assertEquals(["has", target, "1"], log[4]);
834 assertEquals(["get", target, "1", obj], log[5]);
835
836 log.length = 0;
837 assertEquals(["a", "b"], Array.prototype.concat.apply(obj));
838 assertEquals(6, log.length);
839 for (var i in log) assertSame(target, log[i][1]);
840 assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
841 assertEquals(["get", target, "length", obj], log[1]);
842 assertEquals(["has", target, "0"], log[2]);
843 assertEquals(["get", target, "0", obj], log[3]);
844 assertEquals(["has", target, "1"], log[4]);
845 assertEquals(["get", target, "1", obj], log[5]);
846 })();
847
848
849 (function testSpreadableArrayLikeProxyWithNontrivialLength() {
850 var getTrap = function(t, key) {
851 if (key === "length") return {[Symbol.toPrimitive]() {return 3}};
852 if (key === "2") return "baz";
853 if (key === "3") return "bar";
854 };
855 var target = [];
856 var obj = new Proxy(target, {get: getTrap, has: () => true});
857
858 assertEquals([undefined, undefined, "baz"], [].concat(obj));
859 assertEquals([undefined, undefined, "baz"], Array.prototype.concat.apply(obj))
860 })();
861
862
863 (function testSpreadableArrayLikeProxyWithBogusLength() {
864 var getTrap = function(t, key) {
865 if (key === "length") return Symbol();
866 if (key === "2") return "baz";
867 if (key === "3") return "bar";
868 };
869 var target = [];
870 var obj = new Proxy(target, {get: getTrap, has: () => true});
871
872 assertThrows(() => [].concat(obj), TypeError);
873 assertThrows(() => Array.prototype.concat.apply(obj), TypeError);
874 })();
OLDNEW
« no previous file with comments | « test/mjsunit/es6/regexp-tolength.js ('k') | test/mjsunit/harmony/block-for-sloppy.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698