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

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

Issue 771863002: Add Array.prototype.includes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase on master 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
« no previous file with comments | « src/runtime.js ('k') | test/mjsunit/harmony/array-includes-to-object-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-array-includes
6
7 // Largely ported from
8 // https://github.com/tc39/Array.prototype.includes/tree/master/test
9 // using https://www.npmjs.org/package/test262-to-mjsunit with further edits
10
11
12 // Array.prototype.includes sees a new element added by a getter that is hit
13 // during iteration
14 (function() {
15 var arrayLike = {
16 length: 5,
17 0: "a",
18
19 get 1() {
20 this[2] = "c";
21 return "b";
22 }
23 };
24
25 assertTrue(Array.prototype.includes.call(arrayLike, "c"));
26 })();
27
28
29 // Array.prototype.includes works on array-like objects
30 (function() {
31 var arrayLike1 = {
32 length: 5,
33 0: "a",
34 1: "b"
35 };
36
37 assertTrue(Array.prototype.includes.call(arrayLike1, "a"));
38 assertFalse(Array.prototype.includes.call(arrayLike1, "c"));
39
40 var arrayLike2 = {
41 length: 2,
42 0: "a",
43 1: "b",
44 2: "c"
45 };
46
47 assertTrue(Array.prototype.includes.call(arrayLike2, "b"));
48 assertFalse(Array.prototype.includes.call(arrayLike2, "c"));
49 })();
50
51
52 // Array.prototype.includes should fail if used on a null or undefined this
53 (function() {
54 assertThrows(function() {
55 Array.prototype.includes.call(null, "a");
56 }, TypeError);
57
58 assertThrows(function() {
59 Array.prototype.includes.call(undefined, "a");
60 }, TypeError);
61 })();
62
63
64 // Array.prototype.includes should terminate if getting an index throws an
65 // exception
66 (function() {
67 function Test262Error() {}
68
69 var trappedZero = {
70 length: 2,
71
72 get 0() {
73 throw new Test262Error();
74 },
75
76 get 1() {
77 assertUnreachable("Should not try to get the first element");
78 }
79 };
80
81 assertThrows(function() {
82 Array.prototype.includes.call(trappedZero, "a");
83 }, Test262Error);
84 })();
85
86
87 // Array.prototype.includes should terminate if ToNumber ends up being called on
88 // a symbol fromIndex
89 (function() {
90 var trappedZero = {
91 length: 1,
92
93 get 0() {
94 assertUnreachable("Should not try to get the zeroth element");
95 }
96 };
97
98 assertThrows(function() {
99 Array.prototype.includes.call(trappedZero, "a", Symbol());
100 }, TypeError);
101 })();
102
103
104 // Array.prototype.includes should terminate if an exception occurs converting
105 // the fromIndex to a number
106 (function() {
107 function Test262Error() {}
108
109 var fromIndex = {
110 valueOf: function() {
111 throw new Test262Error();
112 }
113 };
114
115 var trappedZero = {
116 length: 1,
117
118 get 0() {
119 assertUnreachable("Should not try to get the zeroth element");
120 }
121 };
122
123 assertThrows(function() {
124 Array.prototype.includes.call(trappedZero, "a", fromIndex);
125 }, Test262Error);
126 })();
127
128
129 // Array.prototype.includes should terminate if an exception occurs getting the
130 // length
131 (function() {
132 function Test262Error() {}
133
134 var fromIndexTrap = {
135 valueOf: function() {
136 assertUnreachable("Should not try to call ToInteger on valueOf");
137 }
138 };
139
140 var throwingLength = {
141 get length() {
142 throw new Test262Error();
143 },
144
145 get 0() {
146 assertUnreachable("Should not try to get the zeroth element");
147 }
148 };
149
150 assertThrows(function() {
151 Array.prototype.includes.call(throwingLength, "a", fromIndexTrap);
152 }, Test262Error);
153 })();
154
155
156 // Array.prototype.includes should terminate if ToLength ends up being called on
157 // a symbol length
158 (function() {
159 var fromIndexTrap = {
160 valueOf: function() {
161 assertUnreachable("Should not try to call ToInteger on valueOf");
162 }
163 };
164
165 var badLength = {
166 length: Symbol(),
167
168 get 0() {
169 assertUnreachable("Should not try to get the zeroth element");
170 }
171 };
172
173 assertThrows(function() {
174 Array.prototype.includes.call(badLength, "a", fromIndexTrap);
175 }, TypeError);
176 })();
177
178
179 // Array.prototype.includes should terminate if an exception occurs converting
180 // the length to a number
181 (function() {
182 function Test262Error() {}
183
184 var fromIndexTrap = {
185 valueOf: function() {
186 assertUnreachable("Should not try to call ToInteger on valueOf");
187 }
188 };
189
190 var badLength = {
191 length: {
192 valueOf: function() {
193 throw new Test262Error();
194 }
195 },
196
197 get 0() {
198 assertUnreachable("Should not try to get the zeroth element");
199 }
200 };
201
202 assertThrows(function() {
203 Array.prototype.includes.call(badLength, "a", fromIndexTrap);
204 }, Test262Error);
205 })();
206
207
208 // Array.prototype.includes should search the whole array, as the optional
209 // second argument fromIndex defaults to 0
210 (function() {
211 assertTrue([10, 11].includes(10));
212 assertTrue([10, 11].includes(11));
213
214 var arrayLike = {
215 length: 2,
216
217 get 0() {
218 return "1";
219 },
220
221 get 1() {
222 return "2";
223 }
224 };
225
226 assertTrue(Array.prototype.includes.call(arrayLike, "1"));
227 assertTrue(Array.prototype.includes.call(arrayLike, "2"));
228 })();
229
230
231 // Array.prototype.includes returns false if fromIndex is greater or equal to
232 // the length of the array
233 (function() {
234 assertFalse([1, 2].includes(2, 3));
235 assertFalse([1, 2].includes(2, 2));
236
237 var arrayLikeWithTrap = {
238 length: 2,
239
240 get 0() {
241 assertUnreachable("Getter for 0 was called");
242 },
243
244 get 1() {
245 assertUnreachable("Getter for 1 was called");
246 }
247 };
248
249 assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, "c", 2));
250 assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, "c", 3));
251 })();
252
253
254 // Array.prototype.includes searches the whole array if the computed index from
255 // the given negative fromIndex argument is less than 0
256 (function() {
257 assertTrue([1, 3].includes(1, -4));
258 assertTrue([1, 3].includes(3, -4));
259
260 var arrayLike = {
261 length: 2,
262 0: "a",
263
264 get 1() {
265 return "b";
266 },
267
268 get "-1"() {
269 assertUnreachable("Should not try to get the element at index -1");
270 }
271 };
272
273 assertTrue(Array.prototype.includes.call(arrayLike, "a", -4));
274 assertTrue(Array.prototype.includes.call(arrayLike, "b", -4));
275 })();
276
277
278 // Array.prototype.includes should use a negative value as the offset from the
279 // end of the array to compute fromIndex
280 (function() {
281 assertTrue([12, 13].includes(13, -1));
282 assertFalse([12, 13].includes(12, -1));
283 assertTrue([12, 13].includes(12, -2));
284
285 var arrayLike = {
286 length: 2,
287
288 get 0() {
289 return "a";
290 },
291
292 get 1() {
293 return "b";
294 }
295 };
296
297 assertTrue(Array.prototype.includes.call(arrayLike, "b", -1));
298 assertFalse(Array.prototype.includes.call(arrayLike, "a", -1));
299 assertTrue(Array.prototype.includes.call(arrayLike, "a", -2));
300 })();
301
302
303 // Array.prototype.includes converts its fromIndex parameter to an integer
304 (function() {
305 assertFalse(["a", "b"].includes("a", 2.3));
306
307 var arrayLikeWithTraps = {
308 length: 2,
309
310 get 0() {
311 assertUnreachable("Getter for 0 was called");
312 },
313
314 get 1() {
315 assertUnreachable("Getter for 1 was called");
316 }
317 };
318
319 assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "c", 2.1));
320 assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "c", +Infinity)) ;
321 assertTrue(["a", "b", "c"].includes("a", -Infinity));
322 assertTrue(["a", "b", "c"].includes("c", 2.9));
323 assertTrue(["a", "b", "c"].includes("c", NaN));
324
325 var arrayLikeWithTrapAfterZero = {
326 length: 2,
327
328 get 0() {
329 return "a";
330 },
331
332 get 1() {
333 assertUnreachable("Getter for 1 was called");
334 }
335 };
336
337 assertTrue(Array.prototype.includes.call(arrayLikeWithTrapAfterZero, "a", NaN) );
338
339 var numberLike = {
340 valueOf: function() {
341 return 2;
342 }
343 };
344
345 assertFalse(["a", "b", "c"].includes("a", numberLike));
346 assertFalse(["a", "b", "c"].includes("a", "2"));
347 assertTrue(["a", "b", "c"].includes("c", numberLike));
348 assertTrue(["a", "b", "c"].includes("c", "2"));
349 })();
350
351
352 // Array.prototype.includes should have length 1
353 (function() {
354 assertEquals(1, Array.prototype.includes.length);
355 })();
356
357
358 // Array.prototype.includes should have name property with value 'includes'
359 (function() {
360 assertEquals("includes", Array.prototype.includes.name);
361 })();
362
363
364 // !!! Test failed to convert:
365 // Cannot convert tests with includes.
366 // !!!
367
368
369 // Array.prototype.includes does not skip holes; if the array has a prototype it
370 // gets from that
371 (function() {
372 var holesEverywhere = [,,,];
373
374 holesEverywhere.__proto__ = {
375 1: "a"
376 };
377
378 holesEverywhere.__proto__.__proto__ = Array.prototype;
379 assertTrue(holesEverywhere.includes("a"));
380 var oneHole = ["a", "b",, "d"];
381
382 oneHole.__proto__ = {
383 get 2() {
384 return "c";
385 }
386 };
387
388 assertTrue(Array.prototype.includes.call(oneHole, "c"));
389 })();
390
391
392 // Array.prototype.includes does not skip holes; instead it treates them as
393 // undefined
394 (function() {
395 assertTrue([,,,].includes(undefined));
396 assertTrue(["a", "b",, "d"].includes(undefined));
397 })();
398
399
400 // Array.prototype.includes gets length property from the prototype if it's
401 // available
402 (function() {
403 var proto = {
404 length: 1
405 };
406
407 var arrayLike = Object.create(proto);
408 arrayLike[0] = "a";
409
410 Object.defineProperty(arrayLike, "1", {
411 get: function() {
412 assertUnreachable("Getter for 1 was called");
413 }
414 });
415
416 assertTrue(Array.prototype.includes.call(arrayLike, "a"));
417 })();
418
419
420 // Array.prototype.includes treats a missing length property as zero
421 (function() {
422 var arrayLikeWithTraps = {
423 get 0() {
424 assertUnreachable("Getter for 0 was called");
425 },
426
427 get 1() {
428 assertUnreachable("Getter for 1 was called");
429 }
430 };
431
432 assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "a"));
433 })();
434
435
436 // Array.prototype.includes should always return false on negative-length
437 // objects
438 (function() {
439 assertFalse(Array.prototype.includes.call({
440 length: -1
441 }, 2));
442
443 assertFalse(Array.prototype.includes.call({
444 length: -2
445 }));
446
447 assertFalse(Array.prototype.includes.call({
448 length: -Infinity
449 }, undefined));
450
451 assertFalse(Array.prototype.includes.call({
452 length: -Math.pow(2, 53)
453 }, NaN));
454
455 assertFalse(Array.prototype.includes.call({
456 length: -1,
457 "-1": 2
458 }, 2));
459
460 assertFalse(Array.prototype.includes.call({
461 length: -3,
462 "-1": 2
463 }, 2));
464
465 assertFalse(Array.prototype.includes.call({
466 length: -Infinity,
467 "-1": 2
468 }, 2));
469
470 var arrayLikeWithTrap = {
471 length: -1,
472
473 get 0() {
474 assertUnreachable("Getter for 0 was called");
475 }
476 };
477
478 assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, 2));
479 })();
480
481
482 // Array.prototype.includes should clamp positive lengths to 2^53 - 1
483 (function() {
484 var fromIndexForLargeIndexTests = 9007199254740990;
485
486 assertFalse(Array.prototype.includes.call({
487 length: 1
488 }, 2));
489
490 assertTrue(Array.prototype.includes.call({
491 length: 1,
492 0: "a"
493 }, "a"));
494
495 assertTrue(Array.prototype.includes.call({
496 length: +Infinity,
497 0: "a"
498 }, "a"));
499
500 assertFalse(Array.prototype.includes.call({
501 length: +Infinity
502 }, "a", fromIndexForLargeIndexTests));
503
504 var arrayLikeWithTrap = {
505 length: +Infinity,
506
507 get 9007199254740992() {
508 assertUnreachable("Getter for 9007199254740992 (i.e. 2^53) was called");
509 },
510
511 "9007199254740993": "a"
512 };
513
514 assertFalse(
515 Array.prototype.includes.call(arrayLikeWithTrap, "a", fromIndexForLargeIndex Tests)
516 );
517
518 var arrayLikeWithTooBigLength = {
519 length: 9007199254740996,
520 "9007199254740992": "a"
521 };
522
523 assertFalse(
524 Array.prototype.includes.call(arrayLikeWithTooBigLength, "a", fromIndexForLa rgeIndexTests)
525 );
526 })();
527
528
529 // Array.prototype.includes should always return false on zero-length objects
530 (function() {
531 assertFalse([].includes(2));
532 assertFalse([].includes());
533 assertFalse([].includes(undefined));
534 assertFalse([].includes(NaN));
535
536 assertFalse(Array.prototype.includes.call({
537 length: 0
538 }, 2));
539
540 assertFalse(Array.prototype.includes.call({
541 length: 0
542 }));
543
544 assertFalse(Array.prototype.includes.call({
545 length: 0
546 }, undefined));
547
548 assertFalse(Array.prototype.includes.call({
549 length: 0
550 }, NaN));
551
552 assertFalse(Array.prototype.includes.call({
553 length: 0,
554 0: 2
555 }, 2));
556
557 assertFalse(Array.prototype.includes.call({
558 length: 0,
559 0: undefined
560 }));
561
562 assertFalse(Array.prototype.includes.call({
563 length: 0,
564 0: undefined
565 }, undefined));
566
567 assertFalse(Array.prototype.includes.call({
568 length: 0,
569 0: NaN
570 }, NaN));
571
572 var arrayLikeWithTrap = {
573 length: 0,
574
575 get 0() {
576 assertUnreachable("Getter for 0 was called");
577 }
578 };
579
580 Array.prototype.includes.call(arrayLikeWithTrap);
581
582 var trappedFromIndex = {
583 valueOf: function() {
584 assertUnreachable("Should not try to convert fromIndex to a number on a ze ro-length array");
585 }
586 };
587
588 [].includes("a", trappedFromIndex);
589
590 Array.prototype.includes.call({
591 length: 0
592 }, trappedFromIndex);
593 })();
594
595
596 // Array.prototype.includes works on objects
597 (function() {
598 assertFalse(["a", "b", "c"].includes({}));
599 assertFalse([{}, {}].includes({}));
600 var obj = {};
601 assertTrue([obj].includes(obj));
602 assertFalse([obj].includes(obj, 1));
603 assertTrue([obj, obj].includes(obj, 1));
604
605 var stringyObject = {
606 toString: function() {
607 return "a";
608 }
609 };
610
611 assertFalse(["a", "b", obj].includes(stringyObject));
612 })();
613
614
615 // Array.prototype.includes does not see an element removed by a getter that is
616 // hit during iteration
617 (function() {
618 var arrayLike = {
619 length: 5,
620 0: "a",
621
622 get 1() {
623 delete this[2];
624 return "b";
625 },
626
627 2: "c"
628 };
629
630 assertFalse(Array.prototype.includes.call(arrayLike, "c"));
631 })();
632
633
634 // Array.prototype.includes should use the SameValueZero algorithm to compare
635 (function() {
636 assertTrue([1, 2, 3].includes(2));
637 assertFalse([1, 2, 3].includes(4));
638 assertTrue([1, 2, NaN].includes(NaN));
639 assertTrue([1, 2, -0].includes(+0));
640 assertTrue([1, 2, -0].includes(-0));
641 assertTrue([1, 2, +0].includes(-0));
642 assertTrue([1, 2, +0].includes(+0));
643 assertFalse([1, 2, -Infinity].includes(+Infinity));
644 assertTrue([1, 2, -Infinity].includes(-Infinity));
645 assertFalse([1, 2, +Infinity].includes(-Infinity));
646 assertTrue([1, 2, +Infinity].includes(+Infinity));
647 })();
648
649
650 // Array.prototype.includes stops once it hits the length of an array-like, even
651 // if there are more after
652 (function() {
653 var arrayLike = {
654 length: 2,
655 0: "a",
656 1: "b",
657
658 get 2() {
659 assertUnreachable("Should not try to get the second element");
660 }
661 };
662
663 assertFalse(Array.prototype.includes.call(arrayLike, "c"));
664 })();
665
666
667 // Array.prototype.includes works on typed arrays
668 (function() {
669 assertTrue(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 2));
670
671 assertTrue(
672 Array.prototype.includes.call(new Float32Array([2.5, 3.14, Math.PI]), 3.1415 927410125732)
673 );
674
675 assertFalse(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 4));
676 assertFalse(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 2, 2));
677 })();
OLDNEW
« no previous file with comments | « src/runtime.js ('k') | test/mjsunit/harmony/array-includes-to-object-sloppy.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698