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

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