blob: eebf99aef5eab829be1d58bff31ac0c3a65d3bce [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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'use strict';
6
7
8function ID(x) {
9 return x;
10}
11
12
13(function TestClassMethodString() {
14 class C {
15 a() { return 'A'}
16 ['b']() { return 'B'; }
17 c() { return 'C'; }
18 [ID('d')]() { return 'D'; }
19 }
20 assertEquals('A', new C().a());
21 assertEquals('B', new C().b());
22 assertEquals('C', new C().c());
23 assertEquals('D', new C().d());
24 assertArrayEquals([], Object.keys(C.prototype));
25 assertArrayEquals(['constructor', 'a', 'b', 'c', 'd'],
26 Object.getOwnPropertyNames(C.prototype));
27})();
28
29
30(function TestClassMethodNumber() {
31 class C {
32 a() { return 'A'; }
33 [1]() { return 'B'; }
34 c() { return 'C'; }
35 [ID(2)]() { return 'D'; }
36 }
37 assertEquals('A', new C().a());
38 assertEquals('B', new C()[1]());
39 assertEquals('C', new C().c());
40 assertEquals('D', new C()[2]());
41 // Array indexes first.
42 assertArrayEquals([], Object.keys(C.prototype));
43 assertArrayEquals(['1', '2', 'constructor', 'a', 'c'],
44 Object.getOwnPropertyNames(C.prototype));
45})();
46
47
48(function TestClassMethodSymbol() {
49 var sym1 = Symbol();
50 var sym2 = Symbol();
51 class C {
52 a() { return 'A'; }
53 [sym1]() { return 'B'; }
54 c() { return 'C'; }
55 [ID(sym2)]() { return 'D'; }
56 }
57 assertEquals('A', new C().a());
58 assertEquals('B', new C()[sym1]());
59 assertEquals('C', new C().c());
60 assertEquals('D', new C()[sym2]());
61 assertArrayEquals([], Object.keys(C.prototype));
62 assertArrayEquals(['constructor', 'a', 'c'],
63 Object.getOwnPropertyNames(C.prototype));
64 assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C.prototype));
65})();
66
67
68
69(function TestStaticClassMethodString() {
70 class C {
71 static a() { return 'A'}
72 static ['b']() { return 'B'; }
73 static c() { return 'C'; }
74 static ['d']() { return 'D'; }
75 }
76 assertEquals('A', C.a());
77 assertEquals('B', C.b());
78 assertEquals('C', C.c());
79 assertEquals('D', C.d());
80 assertArrayEquals([], Object.keys(C));
81 // TODO(arv): It is not clear that we are adding the "standard" properties
82 // in the right order. As far as I can tell the spec adds them in alphabetical
83 // order.
84 assertArrayEquals(['length', 'name', 'prototype', 'a', 'b', 'c', 'd'],
85 Object.getOwnPropertyNames(C));
86})();
87
88
89(function TestStaticClassMethodNumber() {
90 class C {
91 static a() { return 'A'; }
92 static [1]() { return 'B'; }
93 static c() { return 'C'; }
94 static [2]() { return 'D'; }
95 }
96 assertEquals('A', C.a());
97 assertEquals('B', C[1]());
98 assertEquals('C', C.c());
99 assertEquals('D', C[2]());
100 // Array indexes first.
101 assertArrayEquals([], Object.keys(C));
102 assertArrayEquals(['1', '2', 'length', 'name', 'prototype', 'a', 'c'],
103 Object.getOwnPropertyNames(C));
104})();
105
106
107(function TestStaticClassMethodSymbol() {
108 var sym1 = Symbol();
109 var sym2 = Symbol();
110 class C {
111 static a() { return 'A'; }
112 static [sym1]() { return 'B'; }
113 static c() { return 'C'; }
114 static [sym2]() { return 'D'; }
115 }
116 assertEquals('A', C.a());
117 assertEquals('B', C[sym1]());
118 assertEquals('C', C.c());
119 assertEquals('D', C[sym2]());
120 assertArrayEquals([], Object.keys(C));
121 assertArrayEquals(['length', 'name', 'prototype', 'a', 'c'],
122 Object.getOwnPropertyNames(C));
123 assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C));
124})();
125
126
127
128function assertIteratorResult(value, done, result) {
129 assertEquals({ value: value, done: done}, result);
130}
131
132
133(function TestGeneratorComputedName() {
134 class C {
135 *['a']() {
136 yield 1;
137 yield 2;
138 }
139 }
140 var iter = new C().a();
141 assertIteratorResult(1, false, iter.next());
142 assertIteratorResult(2, false, iter.next());
143 assertIteratorResult(undefined, true, iter.next());
144 assertArrayEquals([], Object.keys(C.prototype));
145 assertArrayEquals(['constructor', 'a'],
146 Object.getOwnPropertyNames(C.prototype));
147})();
148
149
150(function TestToNameSideEffects() {
151 var counter = 0;
152 var key1 = {
153 toString: function() {
154 assertEquals(0, counter++);
155 return 'b';
156 }
157 };
158 var key2 = {
159 toString: function() {
160 assertEquals(1, counter++);
161 return 'd';
162 }
163 };
164 class C {
165 a() { return 'A'; }
166 [key1]() { return 'B'; }
167 c() { return 'C'; }
168 [key2]() { return 'D'; }
169 }
170 assertEquals(2, counter);
171 assertEquals('A', new C().a());
172 assertEquals('B', new C().b());
173 assertEquals('C', new C().c());
174 assertEquals('D', new C().d());
175 assertArrayEquals([], Object.keys(C.prototype));
176 assertArrayEquals(['constructor', 'a', 'b', 'c', 'd'],
177 Object.getOwnPropertyNames(C.prototype));
178})();
179
180
181(function TestToNameSideEffectsNumbers() {
182 var counter = 0;
183 var key1 = {
184 valueOf: function() {
185 assertEquals(0, counter++);
186 return 1;
187 },
188 toString: null
189 };
190 var key2 = {
191 valueOf: function() {
192 assertEquals(1, counter++);
193 return 2;
194 },
195 toString: null
196 };
197
198 class C {
199 a() { return 'A'; }
200 [key1]() { return 'B'; }
201 c() { return 'C'; }
202 [key2]() { return 'D'; }
203 }
204 assertEquals(2, counter);
205 assertEquals('A', new C().a());
206 assertEquals('B', new C()[1]());
207 assertEquals('C', new C().c());
208 assertEquals('D', new C()[2]());
209 // Array indexes first.
210 assertArrayEquals([], Object.keys(C.prototype));
211 assertArrayEquals(['1', '2', 'constructor', 'a', 'c'],
212 Object.getOwnPropertyNames(C.prototype));
213})();
214
215
216(function TestGetter() {
217 class C {
218 get ['a']() {
219 return 'A';
220 }
221 }
222 assertEquals('A', new C().a);
223
224 class C2 {
225 get b() {
226 assertUnreachable();
227 }
228 get ['b']() {
229 return 'B';
230 }
231 }
232 assertEquals('B', new C2().b);
233
234 class C3 {
235 get c() {
236 assertUnreachable();
237 }
238 get ['c']() {
239 assertUnreachable();
240 }
241 get ['c']() {
242 return 'C';
243 }
244 }
245 assertEquals('C', new C3().c);
246
247 class C4 {
248 get ['d']() {
249 assertUnreachable();
250 }
251 get d() {
252 return 'D';
253 }
254 }
255 assertEquals('D', new C4().d);
256})();
257
258
259(function TestSetter() {
260 var calls = 0;
261 class C {
262 set ['a'](_) {
263 calls++;
264 }
265 }
266 new C().a = 'A';
267 assertEquals(1, calls);
268
269 calls = 0;
270 class C2 {
271 set b(_) {
272 assertUnreachable();
273 }
274 set ['b'](_) {
275 calls++;
276 }
277 }
278 new C2().b = 'B';
279 assertEquals(1, calls);
280
281 calls = 0;
282 class C3 {
283 set c(_) {
284 assertUnreachable()
285 }
286 set ['c'](_) {
287 assertUnreachable()
288 }
289 set ['c'](_) {
290 calls++
291 }
292 }
293 new C3().c = 'C';
294 assertEquals(1, calls);
295
296 calls = 0;
297 class C4 {
298 set ['d'](_) {
299 assertUnreachable()
300 }
301 set d(_) {
302 calls++
303 }
304 }
305 new C4().d = 'D';
306 assertEquals(1, calls);
307})();
308
309
310(function TestPrototype() {
311 assertThrows(function() {
312 class C {
313 static ['prototype']() {
314 return 1;
315 }
316 }
317 }, TypeError);
318
319 assertThrows(function() {
320 class C2 {
321 static get ['prototype']() {
322 return 2;
323 }
324 }
325 }, TypeError);
326
327 assertThrows(function() {
328 class C3 {
329 static set ['prototype'](x) {
330 assertEquals(3, x);
331 }
332 }
333 }, TypeError);
334
335 assertThrows(function() {
336 class C4 {
337 static *['prototype']() {
338 yield 1;
339 yield 2;
340 }
341 }
342 }, TypeError);
343})();
344
345
346(function TestPrototypeConcat() {
347 assertThrows(function() {
348 class C {
349 static ['pro' + 'tot' + 'ype']() {
350 return 1;
351 }
352 }
353 }, TypeError);
354
355 assertThrows(function() {
356 class C2 {
357 static get ['pro' + 'tot' + 'ype']() {
358 return 2;
359 }
360 }
361 }, TypeError);
362
363 assertThrows(function() {
364 class C3 {
365 static set ['pro' + 'tot' + 'ype'](x) {
366 assertEquals(3, x);
367 }
368 }
369 }, TypeError);
370
371 assertThrows(function() {
372 class C4 {
373 static *['pro' + 'tot' + 'ype']() {
374 yield 1;
375 yield 2;
376 }
377 }
378 }, TypeError);
379})();
380
381
382(function TestConstructor() {
383 // Normally a constructor property is not allowed.
384 class C {
385 ['constructor']() {
386 return 1;
387 }
388 }
389 assertTrue(C !== C.prototype.constructor);
390 assertEquals(1, new C().constructor());
391
392 class C2 {
393 get ['constructor']() {
394 return 2;
395 }
396 }
397 assertEquals(2, new C2().constructor);
398
399 var calls = 0;
400 class C3 {
401 set ['constructor'](x) {
402 assertEquals(3, x);
403 calls++;
404 }
405 }
406 new C3().constructor = 3;
407 assertEquals(1, calls);
408
409 class C4 {
410 *['constructor']() {
411 yield 1;
412 yield 2;
413 }
414 }
415 var iter = new C4().constructor();
416 assertIteratorResult(1, false, iter.next());
417 assertIteratorResult(2, false, iter.next());
418 assertIteratorResult(undefined, true, iter.next());
419})();
420
421
422(function TestExceptionInName() {
423 function MyError() {};
424 function throwMyError() {
425 throw new MyError();
426 }
427 assertThrows(function() {
428 class C {
429 [throwMyError()]() {}
430 }
431 }, MyError);
432 assertThrows(function() {
433 class C {
434 get [throwMyError()]() { return 42; }
435 }
436 }, MyError);
437 assertThrows(function() {
438 class C {
439 set [throwMyError()](_) { }
440 }
441 }, MyError);
442})();
443
444
445(function TestTdzName() {
446 assertThrows(function() {
447 class C {
448 [C]() {}
449 }
450 }, ReferenceError);
451 assertThrows(function() {
452 class C {
453 get [C]() { return 42; }
454 }
455 }, ReferenceError);
456 assertThrows(function() {
457 class C {
458 set [C](_) { }
459 }
460 }, ReferenceError);
461})();