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

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

Issue 1560763002: Add Array support for @@species and subclassing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Last couple comments Created 4 years, 11 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 | « src/runtime/runtime-array.cc ('k') | test/mjsunit/mjsunit.status » ('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 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 --harmony-proxies
6
7 // Test the ES2015 @@species feature
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().slice().constructor);
18 assertEquals(MyArray, new MyArray().splice().constructor);
19
20 // Subclasses can override @@species to return the another class
21
22 class MyOtherArray extends Array {
23 static get [Symbol.species]() { return MyArray; }
24 }
25
26 assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor);
27 assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor);
28 assertEquals(MyArray, new MyOtherArray().slice().constructor);
29 assertEquals(MyArray, new MyOtherArray().splice().constructor);
30
31 // Array methods on non-arrays return arrays
32
33 class MyNonArray extends Array {
34 static get [Symbol.species]() { return MyObject; }
35 }
36
37 class MyObject { }
38
39 assertEquals(MyObject,
40 Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor);
41 assertEquals(MyObject,
42 Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor);
43 assertEquals(MyObject,
44 Array.prototype.slice.call(new MyNonArray()).constructor);
45 assertEquals(MyObject,
46 Array.prototype.splice.call(new MyNonArray()).constructor);
47
48 assertEquals(undefined,
49 Array.prototype.map.call(new MyNonArray(), ()=>{}).length);
50 assertEquals(undefined,
51 Array.prototype.filter.call(new MyNonArray(), ()=>{}).length);
52 // slice and splice actually do explicitly define the length for some reason
53 assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length);
54 assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length);
55
56 // Cross-realm Arrays build same-realm arrays
57
58 var realm = Realm.create();
59 assertEquals(Array,
60 Array.prototype.map.call(
61 Realm.eval(realm, "[]"), ()=>{}).constructor);
62 assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor);
63 assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor"));
64
65 // Defaults when constructor or @@species is missing or non-constructor
66
67 class MyDefaultArray extends Array {
68 static get [Symbol.species]() { return undefined; }
69 }
70 assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor);
71
72 class MyOtherDefaultArray extends Array { }
73 assertEquals(MyOtherDefaultArray,
74 new MyOtherDefaultArray().map(()=>{}).constructor);
75 MyOtherDefaultArray.prototype.constructor = undefined;
76 assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor);
77
78 // Exceptions propagated when getting constructor @@species throws
79
80 class SpeciesError extends Error { }
81 class ConstructorError extends Error { }
82 class MyThrowingArray extends Array {
83 static get [Symbol.species]() { throw new SpeciesError; }
84 }
85 assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
86 Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
87 get() { throw new ConstructorError; }
88 });
89 assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
90
91 // Previously unexpected errors from setting properties in arrays throw
92
93 class FrozenArray extends Array {
94 constructor(...args) {
95 super(...args);
96 Object.freeze(this);
97 }
98 }
99 assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError);
100 assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError);
101 assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError);
102 assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError);
103
104 // Verify call counts and constructor parameters
105
106 var count;
107 var params;
108 class MyObservedArray extends Array {
109 constructor(...args) {
110 super(...args);
111 params = args;
112 }
113 static get [Symbol.species]() {
114 count++
115 return this;
116 }
117 }
118
119 count = 0;
120 params = undefined;
121 assertEquals(MyObservedArray,
122 new MyObservedArray().map(()=>{}).constructor);
123 assertEquals(1, count);
124 assertArrayEquals([0], params);
125
126 count = 0;
127 params = undefined;
128 assertEquals(MyObservedArray,
129 new MyObservedArray().filter(()=>{}).constructor);
130 assertEquals(1, count);
131 assertArrayEquals([0], params);
132
133 count = 0;
134 params = undefined;
135 assertEquals(MyObservedArray,
136 new MyObservedArray().slice().constructor);
137 // TODO(littledan): Should be 1
138 assertEquals(2, count);
139 assertArrayEquals([0], params);
140
141 count = 0;
142 params = undefined;
143 assertEquals(MyObservedArray,
144 new MyObservedArray().splice().constructor);
145 // TODO(littledan): Should be 1
146 assertEquals(2, count);
147 assertArrayEquals([0], params);
148
149 // @@species constructor can be a Proxy, and the realm access doesn't
150 // crash
151
152 class MyProxyArray extends Array { }
153 let ProxyArray = new Proxy(MyProxyArray, {});
154 MyProxyArray.constructor = ProxyArray;
155
156 assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor);
OLDNEW
« no previous file with comments | « src/runtime/runtime-array.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698