Home | History | Annotate | Download | only in es6
      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 'use strict';
      6 
      7 
      8 function 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 
    128 function 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 })();
    462