OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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-species | |
6 | |
7 // Test the ES2015 @@species feature | |
adamk
2016/01/06 00:10:12
More tests I'd like to see:
- Test that the lengt
Dan Ehrenberg
2016/01/07 00:42:58
Added those tests at the end
| |
8 | |
9 'use strict'; | |
10 | |
11 // Subclasses of Array construct themselves under map, etc | |
12 | |
13 class MyArray extends Array { } | |
14 | |
15 assertEquals(MyArray, new MyArray().map(()=>{}).constructor); | |
16 assertEquals(MyArray, new MyArray().filter(()=>{}).constructor); | |
17 assertEquals(MyArray, new MyArray().concat().constructor); | |
18 assertEquals(MyArray, new MyArray().slice().constructor); | |
19 assertEquals(MyArray, new MyArray().splice().constructor); | |
20 | |
21 // Subclasses can override @@species to return the another class | |
22 | |
23 class MyOtherArray extends Array { | |
24 static get [Symbol.species]() { return MyArray; } | |
25 } | |
26 | |
27 assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor); | |
28 assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor); | |
29 assertEquals(MyArray, new MyOtherArray().concat().constructor); | |
30 assertEquals(MyArray, new MyOtherArray().slice().constructor); | |
31 assertEquals(MyArray, new MyOtherArray().splice().constructor); | |
32 | |
33 // Array methods on non-arrays return arrays | |
34 | |
35 class MyNonArray extends Array { | |
36 static get [Symbol.species]() { return MyObject; } | |
37 } | |
38 | |
39 class MyObject { } | |
40 | |
41 assertEquals(MyObject, Array.prototype.map.call(new MyNonArray(), ()=>{}).constr uctor); | |
adamk
2016/01/06 00:10:12
Please wrap at 80 chars here and below (dunno why
Dan Ehrenberg
2016/01/07 00:42:58
Fixed
| |
42 assertEquals(MyObject, Array.prototype.filter.call(new MyNonArray(), ()=>{}).con structor); | |
43 assertEquals(MyObject, Array.prototype.concat.call(new MyNonArray()).constructor ); | |
44 assertEquals(MyObject, Array.prototype.slice.call(new MyNonArray()).constructor) ; | |
45 assertEquals(MyObject, Array.prototype.splice.call(new MyNonArray()).constructor ); | |
46 | |
47 assertEquals(undefined, Array.prototype.map.call(new MyNonArray(), ()=>{}).lengt h); | |
48 assertEquals(undefined, Array.prototype.filter.call(new MyNonArray(), ()=>{}).le ngth); | |
49 assertEquals(undefined, Array.prototype.concat.call(new MyNonArray()).length); | |
50 // slice and splice actually do explicitly define the length for some reason | |
51 assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length); | |
52 assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length); | |
53 | |
54 // Cross-realm Arrays build same-realm arrays | |
55 | |
56 var realm = Realm.create(); | |
57 assertEquals(Array, Array.prototype.map.call(Realm.eval(realm, "[]"), ()=>{}).co nstructor); | |
58 assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor); | |
59 assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor")); | |
60 | |
61 // Defaults when constructor or @@species is missing or non-constructor | |
62 | |
63 class MyDefaultArray extends Array { | |
64 static get [Symbol.species]() { return undefined; } | |
65 } | |
66 assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor); | |
67 | |
68 class MyOtherDefaultArray extends Array { } | |
69 assertEquals(MyOtherDefaultArray, new MyOtherDefaultArray().map(()=>{}).construc tor); | |
70 MyOtherDefaultArray.prototype.constructor = undefined; | |
71 assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor); | |
72 | |
73 // Exceptions propagated when getting constructor @@species throws | |
74 | |
75 class SpeciesError extends Error { } | |
76 class ConstructorError extends Error { } | |
77 class MyThrowingArray extends Array { | |
78 static get [Symbol.species]() { throw new SpeciesError; } | |
79 } | |
80 assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError); | |
81 Object.defineProperty(MyThrowingArray.prototype, 'constructor', { | |
82 get() { throw new ConstructorError; } | |
83 }); | |
84 assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError); | |
85 | |
86 // Previously unexpected errors from setting properties in arrays throw | |
87 | |
88 class FrozenArray extends Array { | |
89 constructor(...args) { | |
90 super(...args); | |
91 Object.freeze(this); | |
92 } | |
93 } | |
94 assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError); | |
95 assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError); | |
96 assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError); | |
97 assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError); | |
98 assertThrows(() => new FrozenArray([1]).concat(), TypeError); | |
OLD | NEW |