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

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

Powered by Google App Engine
This is Rietveld 408576698