ES6 class syntax should use block scoping
[WebKit.git] / LayoutTests / js / script-tests / class-syntax-declaration.js
1
2 description('Tests for ES6 class syntax declarations');
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 + ":::" + e.toString() + ":::" + message);
14     }
15     if (!threw)
16         testFailed(s);
17 }
18
19 function shouldNotThrow(s) {
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 var constructorCallCount = 0;
40 var staticMethodValue = [1];
41 var instanceMethodValue = [2];
42 var getterValue = [3];
43 var setterValue = undefined;
44 class A {
45     constructor() { constructorCallCount++; }
46     static someStaticMethod() { return staticMethodValue; }
47     static get someStaticGetter() { return getterValue; }
48     static set someStaticSetter(value) { setterValue = value; }
49     someInstanceMethod() { return instanceMethodValue; }
50     get someGetter() { return getterValue; }
51     set someSetter(value) { setterValue = value; }
52 }
53
54 shouldBe("constructorCallCount", "0");
55 shouldBe("A.someStaticMethod()", "staticMethodValue");
56 shouldBe("A.someStaticGetter", "getterValue");
57 shouldBe("setterValue = undefined; A.someStaticSetter = 123; setterValue", "123");
58 shouldBe("(new A).someInstanceMethod()", "instanceMethodValue");
59 shouldBe("constructorCallCount", "1");
60 shouldBe("(new A).someGetter", "getterValue");
61 shouldBe("constructorCallCount", "2");
62 shouldBe("(new A).someGetter", "getterValue");
63 shouldBe("setterValue = undefined; (new A).someSetter = 789; setterValue", "789");
64 shouldBe("(new A).__proto__", "A.prototype");
65 shouldBe("A.prototype.constructor", "A");
66
67 shouldThrow("class", "'SyntaxError: Unexpected end of script'");
68 shouldThrow("class [", "'SyntaxError: Unexpected token \\'[\\''");
69 shouldThrow("class {", "'SyntaxError: Class statements must have a name.'");
70 shouldThrow("class X {", "'SyntaxError: Unexpected end of script'");
71 shouldThrow("class X { ( }", "'SyntaxError: Unexpected token \\'(\\''");
72 shouldNotThrow("class X {}");
73
74 shouldThrow("class X { constructor() {} constructor() {} }", "'SyntaxError: Cannot declare multiple constructors in a single class.'");
75 shouldThrow("class X { get constructor() {} }", "'SyntaxError: Cannot declare a getter or setter named \\'constructor\\'.'");
76 shouldThrow("class X { set constructor() {} }", "'SyntaxError: Cannot declare a getter or setter named \\'constructor\\'.'");
77 shouldNotThrow("class X { constructor() {} static constructor() { return staticMethodValue; } }");
78 shouldBe("class X { constructor() {} static constructor() { return staticMethodValue; } }; X.constructor()", "staticMethodValue");
79
80 shouldThrow("class X { constructor() {} static prototype() {} }", "'SyntaxError: Cannot declare a static method named \\'prototype\\'.'");
81 shouldThrow("class X { constructor() {} static get prototype() {} }", "'SyntaxError: Cannot declare a static method named \\'prototype\\'.'");
82 shouldThrow("class X { constructor() {} static set prototype() {} }", "'SyntaxError: Cannot declare a static method named \\'prototype\\'.'");
83 shouldNotThrow("class X { constructor() {} prototype() { return instanceMethodValue; } }");
84 shouldBe("class X { constructor() {} prototype() { return instanceMethodValue; } }; (new X).prototype()", "instanceMethodValue");
85
86 shouldNotThrow("class X { constructor() {} set foo(a) {} }");
87 shouldNotThrow("class X { constructor() {} set foo({x, y}) {} }");
88 shouldThrow("class X { constructor() {} set foo() {} }");
89 shouldThrow("class X { constructor() {} set foo(a, b) {} }");
90 shouldNotThrow("class X { constructor() {} get foo() {} }");
91 shouldThrow("class X { constructor() {} get foo(x) {} }");
92 shouldThrow("class X { constructor() {} get foo({x, y}) {} }");
93
94 var successfullyParsed = true;