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

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

Issue 1577043002: Support @@species in Array.prototype.concat (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix exceptions thrown from exceeding array length 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/builtins.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --harmony-species --harmony-proxies 5 // Flags: --harmony-species --harmony-proxies
6 6
7 // Test the ES2015 @@species feature 7 // Test the ES2015 @@species feature
8 8
9 'use strict'; 9 'use strict';
10 10
11 // Subclasses of Array construct themselves under map, etc 11 // Subclasses of Array construct themselves under map, etc
12 12
13 class MyArray extends Array { } 13 class MyArray extends Array { }
14 14
15 assertEquals(MyArray, new MyArray().map(()=>{}).constructor); 15 assertEquals(MyArray, new MyArray().map(()=>{}).constructor);
16 assertEquals(MyArray, new MyArray().filter(()=>{}).constructor); 16 assertEquals(MyArray, new MyArray().filter(()=>{}).constructor);
17 assertEquals(MyArray, new MyArray().slice().constructor); 17 assertEquals(MyArray, new MyArray().slice().constructor);
18 assertEquals(MyArray, new MyArray().splice().constructor); 18 assertEquals(MyArray, new MyArray().splice().constructor);
19 assertEquals(MyArray, new MyArray().concat([1]).constructor);
20 assertEquals(1, new MyArray().concat([1])[0]);
19 21
20 // Subclasses can override @@species to return the another class 22 // Subclasses can override @@species to return the another class
21 23
22 class MyOtherArray extends Array { 24 class MyOtherArray extends Array {
23 static get [Symbol.species]() { return MyArray; } 25 static get [Symbol.species]() { return MyArray; }
24 } 26 }
25 27
26 assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor); 28 assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor);
27 assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor); 29 assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor);
28 assertEquals(MyArray, new MyOtherArray().slice().constructor); 30 assertEquals(MyArray, new MyOtherArray().slice().constructor);
29 assertEquals(MyArray, new MyOtherArray().splice().constructor); 31 assertEquals(MyArray, new MyOtherArray().splice().constructor);
32 assertEquals(MyArray, new MyOtherArray().concat().constructor);
30 33
31 // Array methods on non-arrays return arrays 34 // Array methods on non-arrays return arrays
32 35
33 class MyNonArray extends Array { 36 class MyNonArray extends Array {
34 static get [Symbol.species]() { return MyObject; } 37 static get [Symbol.species]() { return MyObject; }
35 } 38 }
36 39
37 class MyObject { } 40 class MyObject { }
38 41
39 assertEquals(MyObject, 42 assertEquals(MyObject,
40 Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor); 43 Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor);
41 assertEquals(MyObject, 44 assertEquals(MyObject,
42 Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor); 45 Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor);
43 assertEquals(MyObject, 46 assertEquals(MyObject,
44 Array.prototype.slice.call(new MyNonArray()).constructor); 47 Array.prototype.slice.call(new MyNonArray()).constructor);
45 assertEquals(MyObject, 48 assertEquals(MyObject,
46 Array.prototype.splice.call(new MyNonArray()).constructor); 49 Array.prototype.splice.call(new MyNonArray()).constructor);
50 assertEquals(MyObject,
51 Array.prototype.concat.call(new MyNonArray()).constructor);
47 52
48 assertEquals(undefined, 53 assertEquals(undefined,
49 Array.prototype.map.call(new MyNonArray(), ()=>{}).length); 54 Array.prototype.map.call(new MyNonArray(), ()=>{}).length);
50 assertEquals(undefined, 55 assertEquals(undefined,
51 Array.prototype.filter.call(new MyNonArray(), ()=>{}).length); 56 Array.prototype.filter.call(new MyNonArray(), ()=>{}).length);
57 assertEquals(undefined,
58 Array.prototype.concat.call(new MyNonArray(), ()=>{}).length);
52 // slice and splice actually do explicitly define the length for some reason 59 // slice and splice actually do explicitly define the length for some reason
53 assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length); 60 assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length);
54 assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length); 61 assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length);
55 62
56 // Cross-realm Arrays build same-realm arrays 63 // Cross-realm Arrays build same-realm arrays
57 64
58 var realm = Realm.create(); 65 var realm = Realm.create();
59 assertEquals(Array, 66 assertEquals(Array,
60 Array.prototype.map.call( 67 Array.prototype.map.call(
61 Realm.eval(realm, "[]"), ()=>{}).constructor); 68 Realm.eval(realm, "[]"), ()=>{}).constructor);
62 assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor); 69 assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor);
63 assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor")); 70 assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor"));
71 assertEquals(Array,
72 Array.prototype.concat.call(
73 Realm.eval(realm, "[]")).constructor);
64 74
65 // Defaults when constructor or @@species is missing or non-constructor 75 // Defaults when constructor or @@species is missing or non-constructor
66 76
67 class MyDefaultArray extends Array { 77 class MyDefaultArray extends Array {
68 static get [Symbol.species]() { return undefined; } 78 static get [Symbol.species]() { return undefined; }
69 } 79 }
70 assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor); 80 assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor);
71 81
72 class MyOtherDefaultArray extends Array { } 82 class MyOtherDefaultArray extends Array { }
73 assertEquals(MyOtherDefaultArray, 83 assertEquals(MyOtherDefaultArray,
74 new MyOtherDefaultArray().map(()=>{}).constructor); 84 new MyOtherDefaultArray().map(()=>{}).constructor);
75 MyOtherDefaultArray.prototype.constructor = undefined; 85 MyOtherDefaultArray.prototype.constructor = undefined;
76 assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor); 86 assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor);
87 assertEquals(Array, new MyOtherDefaultArray().concat().constructor);
77 88
78 // Exceptions propagated when getting constructor @@species throws 89 // Exceptions propagated when getting constructor @@species throws
79 90
80 class SpeciesError extends Error { } 91 class SpeciesError extends Error { }
81 class ConstructorError extends Error { } 92 class ConstructorError extends Error { }
82 class MyThrowingArray extends Array { 93 class MyThrowingArray extends Array {
83 static get [Symbol.species]() { throw new SpeciesError; } 94 static get [Symbol.species]() { throw new SpeciesError; }
84 } 95 }
85 assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError); 96 assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
86 Object.defineProperty(MyThrowingArray.prototype, 'constructor', { 97 Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
87 get() { throw new ConstructorError; } 98 get() { throw new ConstructorError; }
88 }); 99 });
89 assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError); 100 assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
90 101
91 // Previously unexpected errors from setting properties in arrays throw 102 // Previously unexpected errors from setting properties in arrays throw
92 103
93 class FrozenArray extends Array { 104 class FrozenArray extends Array {
94 constructor(...args) { 105 constructor(...args) {
95 super(...args); 106 super(...args);
96 Object.freeze(this); 107 Object.freeze(this);
97 } 108 }
98 } 109 }
99 assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError); 110 assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError);
100 assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError); 111 assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError);
101 assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError); 112 assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError);
102 assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError); 113 assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError);
114 assertThrows(() => new FrozenArray([]).concat([1]), TypeError);
103 115
104 // Verify call counts and constructor parameters 116 // Verify call counts and constructor parameters
105 117
106 var count; 118 var count;
107 var params; 119 var params;
108 class MyObservedArray extends Array { 120 class MyObservedArray extends Array {
109 constructor(...args) { 121 constructor(...args) {
110 super(...args); 122 super(...args);
111 params = args; 123 params = args;
112 } 124 }
(...skipping 13 matching lines...) Expand all
126 count = 0; 138 count = 0;
127 params = undefined; 139 params = undefined;
128 assertEquals(MyObservedArray, 140 assertEquals(MyObservedArray,
129 new MyObservedArray().filter(()=>{}).constructor); 141 new MyObservedArray().filter(()=>{}).constructor);
130 assertEquals(1, count); 142 assertEquals(1, count);
131 assertArrayEquals([0], params); 143 assertArrayEquals([0], params);
132 144
133 count = 0; 145 count = 0;
134 params = undefined; 146 params = undefined;
135 assertEquals(MyObservedArray, 147 assertEquals(MyObservedArray,
148 new MyObservedArray().concat().constructor);
149 assertEquals(1, count);
150 assertArrayEquals([0], params);
151
152 count = 0;
153 params = undefined;
154 assertEquals(MyObservedArray,
136 new MyObservedArray().slice().constructor); 155 new MyObservedArray().slice().constructor);
137 // TODO(littledan): Should be 1 156 // TODO(littledan): Should be 1
138 assertEquals(2, count); 157 assertEquals(2, count);
139 assertArrayEquals([0], params); 158 assertArrayEquals([0], params);
140 159
141 count = 0; 160 count = 0;
142 params = undefined; 161 params = undefined;
143 assertEquals(MyObservedArray, 162 assertEquals(MyObservedArray,
144 new MyObservedArray().splice().constructor); 163 new MyObservedArray().splice().constructor);
145 // TODO(littledan): Should be 1 164 // TODO(littledan): Should be 1
146 assertEquals(2, count); 165 assertEquals(2, count);
147 assertArrayEquals([0], params); 166 assertArrayEquals([0], params);
148 167
149 // @@species constructor can be a Proxy, and the realm access doesn't 168 // @@species constructor can be a Proxy, and the realm access doesn't
150 // crash 169 // crash
151 170
152 class MyProxyArray extends Array { } 171 class MyProxyArray extends Array { }
153 let ProxyArray = new Proxy(MyProxyArray, {}); 172 let ProxyArray = new Proxy(MyProxyArray, {});
154 MyProxyArray.constructor = ProxyArray; 173 MyProxyArray.constructor = ProxyArray;
155 174
156 assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor); 175 assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor);
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698