[JSC] Do not use asArrayModes() with Structures because it discards TypedArray inform...
[WebKit-https.git] / JSTests / stress / async-arrow-functions-lexical-super-binding.js
1 function shouldBe(expected, actual, msg) {
2     if (msg === void 0)
3         msg = "";
4     else
5         msg = " for " + msg;
6     if (actual !== expected)
7         throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
8 }
9
10 function shouldBeAsync(expected, run, msg) {
11     let actual;
12     var hadError = false;
13     run().then(function(value) { actual = value; },
14                function(error) { hadError = true; actual = error; });
15     drainMicrotasks();
16
17     if (hadError)
18         throw actual;
19
20     shouldBe(expected, actual, msg);
21 }
22
23 class BaseClass {
24     baseClassValue() {
25         return "BaseClassValue";
26     }
27     get property() {
28         return "test!";
29     }
30 }
31
32 class ChildClass extends BaseClass {
33     asyncSuperProp() {
34         return async x => super.baseClassValue();
35     }
36     asyncSuperProp2() {
37         return async x => { return super.baseClassValue(); }
38     }
39 }
40
41 shouldBeAsync("BaseClassValue", new ChildClass().asyncSuperProp());
42 shouldBeAsync("BaseClassValue", new ChildClass().asyncSuperProp2());
43
44 class ChildClass2 extends BaseClass {
45     constructor() {
46         return async (self = super()) => self.baseClassValue() + ' ' + super.property;
47     }
48 }
49
50 shouldBeAsync("BaseClassValue test!", new ChildClass2());
51
52 var error = undefined;
53 var value = undefined;
54
55 class A {
56     constructor() {
57         this._id = 'class-id';
58     }
59 }
60
61 const childA1 = new class extends A {
62   constructor() {
63     var f = async (a=super()) => { return 'abc'; }
64     f().then( val => {value = val; }, err => { error = err;});
65   }
66 }
67
68 drainMicrotasks();
69
70 shouldBe(childA1._id, 'class-id');
71 shouldBe(value, 'abc');
72 shouldBe(error, undefined);
73
74 value = undefined;
75 error = undefined;
76
77 const childA2 = new class extends A {
78   constructor() {
79     var f = async (a) => { super(); return 'abc'; }
80     f().then( val => {value = val; }, err => { error = err;});
81   }
82 }
83
84 drainMicrotasks();
85
86 shouldBe(childA2._id, 'class-id');
87 shouldBe(value, 'abc');
88 shouldBe(error, undefined);
89
90 value = undefined;
91 error = undefined;
92
93 const childA3 = new class extends A {
94     constructor() {
95         var f = async (a = super()) => { super(); return 'abc'; }
96         f().then( val => {value = val; }, err => { error = err;});
97     }
98 }
99
100 drainMicrotasks();
101
102 shouldBe(childA3._id, 'class-id');
103 shouldBe(value, undefined);
104 shouldBe(error.toString(), 'ReferenceError: \'super()\' can\'t be called more than once in a constructor.');
105
106
107 let childA4;
108 let catchError;
109 error = undefined; 
110 try {
111     childA4 = new class extends A {
112         constructor() {
113             var f = async (a) => { await 'await value'; super(); return 'abc'; }
114             f().then(val => { value = val; }, err => { error = err; });
115         }
116     }
117 } catch (err) {
118     catchError = err;  
119 }
120
121 drainMicrotasks();
122
123 shouldBe(childA4, undefined);
124 shouldBe(value, 'abc');
125 shouldBe(error, undefined);
126 shouldBe(catchError.toString(), 'ReferenceError: Cannot access uninitialized variable.');
127
128 catchError = undefined;
129 error = undefined; 
130 value = undefined;
131
132 const childA5 = new class extends A {
133     constructor() {
134         var f = async (a) => { super(); await 'await value'; return 'abc'; }
135         f().then(val => { value = val; }, err => { error = err; });
136     }
137 }
138
139 drainMicrotasks();
140
141 shouldBe(childA5._id, 'class-id');
142 shouldBe(value, 'abc');
143 shouldBe(error, undefined);
144 shouldBe(catchError, undefined);
145
146 function checkClass(classSource) {
147     let base1 = undefined;
148     let error = undefined; 
149     let value = undefined;
150     let catchError = undefined;
151     try {
152         base1 = eval(classSource);
153
154         drainMicrotasks();
155     } catch (err) {
156         catchError = err;  
157     }
158
159     shouldBe(base1, undefined);
160     shouldBe(value, undefined);
161     shouldBe(error, undefined);
162     shouldBe(catchError.toString(), 'SyntaxError: super is not valid in this context.');
163 }
164
165 checkClass(`new class {
166     constructor() {
167         var f = async (a) => { super(); return 'abc'; }
168         f().then(val => { value = val; }, err => { error = err; });
169     }
170 }`);
171
172 checkClass(`new class {
173     constructor() {
174         var f = async (a) => { await 'p'; super(); return 'abc'; }
175         f().then(val => { value = val; }, err => { error = err; });
176     }
177 }`);
178
179 checkClass(`new class {
180     constructor() {
181         var f = async (a) => { super(); await 'p'; return 'abc'; }
182         f().then(val => { value = val; }, err => { error = err; });
183     }
184 }`);
185
186
187 checkClass(`new class extends A {
188     method() {
189         var f = async (a) => { super(); return 'abc'; }
190         f().then(val => { value = val; }, err => { error = err; });
191     }
192 }`);
193
194 checkClass(`new class extends A {
195     get prop() {
196         var f = async (a) => { super(); return 'abc'; }
197         f().then(val => { value = val; }, err => { error = err; });
198     }
199 }`);
200
201 checkClass(`new class extends A {
202     set prop(_value) {
203         var f = async (a) => { super(); return 'abc'; }
204         f().then(val => { value = val; }, err => { error = err; });
205     }
206 }`);