ES6 class syntax should use block scoping
[WebKit.git] / LayoutTests / js / script-tests / class-syntax-super.js
1
2 description('Tests for ES6 class syntax "super"');
3
4 function shouldThrow(s, message) {
5     var threw = false;
6     try {
7         eval(s);
8     } catch(e) {
9         threw = true;
10         if (!message || e.toString() === eval(message))
11             testPassed(s + ":::" + e.toString());
12         else
13             testFailed(s);
14     }
15     if (!threw)
16         testFailed(s);
17 }
18
19 function shouldNotThrow(s, message) {
20     var threw = false;
21     try {
22         eval(s);
23     } catch(e) {
24         threw = true;
25     }
26     if (threw)
27         testFailed(s);
28     else
29         testPassed(s);
30 }
31
32 function shouldBe(a, b) {
33     if (eval(a) === eval(b))
34         testPassed(a + ":::" + b);
35     else
36         testFailed(a + ":::" + b);
37 }
38
39 function shouldBeTrue(s) {
40     if (eval(s) === true)
41         testPassed(s);
42     else 
43         testFailed(s);
44 }
45
46 function shouldBeFalse(s) {
47     if (eval(s) === false)
48         testPassed(s);
49     else 
50         testFailed(s);
51 }
52
53 var baseMethodValue = {};
54 var valueInSetter = null;
55
56 class Base {
57     constructor() { }
58     baseMethod() { return baseMethodValue; }
59     chainMethod() { return 'base'; }
60     static staticMethod() { return 'base3'; }
61 }
62
63 class Derived extends Base {
64     constructor() { super(); }
65     chainMethod() { return [super.chainMethod(), 'derived']; }
66     callBaseMethod() { return super.baseMethod(); }
67     get callBaseMethodInGetter() { return super['baseMethod'](); }
68     set callBaseMethodInSetter(x) { valueInSetter = super.baseMethod(); }
69     get baseMethodInGetterSetter() { return super.baseMethod; }
70     set baseMethodInGetterSetter(x) { valueInSetter = super['baseMethod']; }
71     static staticMethod() { return super.staticMethod(); }
72 }
73
74 class SecondDerived extends Derived {
75     constructor() { super(); }
76     chainMethod() { return super.chainMethod().concat(['secondDerived']); }
77 }
78
79 shouldBeTrue('(new Base) instanceof Base');
80 shouldBeTrue('(new Derived) instanceof Derived');
81 shouldBe('(new Derived).callBaseMethod()', 'baseMethodValue');
82 shouldBe('x = (new Derived).callBaseMethod; x()', 'baseMethodValue');
83 shouldBe('(new Derived).callBaseMethodInGetter', 'baseMethodValue');
84 shouldBe('(new Derived).callBaseMethodInSetter = 1; valueInSetter', 'baseMethodValue');
85 shouldBe('(new Derived).baseMethodInGetterSetter', '(new Base).baseMethod');
86 shouldBe('(new Derived).baseMethodInGetterSetter = 1; valueInSetter', '(new Base).baseMethod');
87 shouldBe('Derived.staticMethod()', '"base3"');
88 shouldBe('(new SecondDerived).chainMethod().toString()', '["base", "derived", "secondDerived"].toString()');
89 shouldThrow('x = class extends Base { constructor() { super(); } super() {} }', '"SyntaxError: Unexpected keyword \'super\'"');
90 shouldThrow('x = class extends Base { constructor() { super(); } method() { super() } }',
91     '"SyntaxError: Cannot call super() outside of a class constructor."');
92 shouldThrow('x = class extends Base { constructor() { super(); } method() { super } }', '"SyntaxError: Cannot reference super."');
93 shouldThrow('x = class extends Base { constructor() { super(); } method() { return new super } }', '"SyntaxError: Cannot use new with super."');
94 shouldNotThrow('x = class extends Base { constructor() { super(); } method1() { delete (super.foo) } method2() { delete super["foo"] } }');
95 shouldThrow('(new x).method1()', '"ReferenceError: Cannot delete a super property"');
96 shouldThrow('(new x).method2()', '"ReferenceError: Cannot delete a super property"');
97 shouldBeTrue('new (class { constructor() { return undefined; } }) instanceof Object');
98 shouldBeTrue('new (class { constructor() { return 1; } }) instanceof Object');
99 shouldThrow('new (class extends Base { constructor() { return undefined } })');
100 shouldBeTrue('new (class extends Base { constructor() { super(); return undefined } }) instanceof Object');
101 shouldBe('x = { }; new (class extends Base { constructor() { return x } });', 'x');
102 shouldBeFalse('x instanceof Base');
103 shouldThrow('new (class extends Base { constructor() { } })', '"ReferenceError: Cannot access uninitialized variable."');
104 shouldThrow('new (class extends Base { constructor() { return 1; } })', '"TypeError: Cannot return a non-object type in the constructor of a derived class."');
105 shouldThrow('new (class extends null { constructor() { return undefined } })');
106 shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: undefined is not an object (evaluating \'super()\')"');
107 shouldBe('x = { }; new (class extends null { constructor() { return x } });', 'x');
108 shouldBeTrue('x instanceof Object');
109 shouldThrow('new (class extends null { constructor() { } })', '"ReferenceError: Cannot access uninitialized variable."');
110 shouldThrow('new (class extends null { constructor() { return 1; } })', '"TypeError: Cannot return a non-object type in the constructor of a derived class."');
111 shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: undefined is not an object (evaluating \'super()\')"');
112 shouldThrow('new (class { constructor() { super() } })', '"SyntaxError: Cannot call super() in a base class constructor."');
113 shouldThrow('function x() { super(); }', '"SyntaxError: Cannot call super() outside of a class constructor."');
114 shouldThrow('new (class extends Object { constructor() { function x() { super() } } })', '"SyntaxError: Cannot call super() outside of a class constructor."');
115 shouldThrow('new (class extends Object { constructor() { function x() { super.method } } })', '"SyntaxError: super can only be used in a method of a derived class."');
116 shouldThrow('function x() { super.method(); }', '"SyntaxError: super can only be used in a method of a derived class."');
117 shouldThrow('function x() { super(); }', '"SyntaxError: Cannot call super() outside of a class constructor."');
118
119 var successfullyParsed = true;