Invalid flags in a RegExp literal should be an early SyntaxError
[WebKit-https.git] / JSTests / stress / async-iteration-yield-star.js
1 var assert = function (result, expected, message = "") {
2   if (result !== expected) {
3     throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
4   }
5 };
6
7 const Logger = function () {
8     var log = [];
9
10     this.logEvent = (type, value, done) => {
11         log.push({ type, value, done});
12     };
13     this.logFulfilledEvent = (value, done) => {
14         this.logEvent('fulfilled', value, done);
15     };
16     this.logRejectEvent = error => {
17         this.logEvent('reject', error.toString(), true);
18     };
19     this.logCatchEvent = value => {
20         this.logEvent('catch', value, true);
21     };
22     this.logCustomEvent = event => {
23         this.logEvent('custom', event, false);
24     };
25     this.getLogger = () => log;
26
27     this.clear = () => {
28         log = [];
29     }
30 };
31
32 const fulfillSpy = logger => result => logger.logFulfilledEvent(result.value, result.done);
33 const rejectSpy = logger => error => logger.logRejectEvent(error);
34 const catchSpy = logger => error => logger.logCatchEvent(error);
35 const customSpy = logger => event => logger.logCustomEvent(event);
36
37 const assertLogger = function (loggerObject) {
38     const logger = loggerObject.getLogger();
39
40     var _assertLogger = function () {
41         let index = 0;
42
43         const isNotOutOfLength = () => {
44             assert(index < logger.length, true, `Index is greater then log length`);   
45         }
46
47         this.fullfilled = function (expectedValue, message = 'on fulfill') {
48             isNotOutOfLength();
49
50             const msg = `step: ${index} - ${message}`;
51             let step = logger[index];
52             assert(step.type, 'fulfilled', msg);
53             assert(step.value, expectedValue, msg);
54             assert(step.done, false, msg);
55
56             index++;
57             return this;
58         };
59
60         this.fullfilledDone = function (expectedValue, message = 'on fulfill with done true') {
61             isNotOutOfLength();
62
63             const msg = `step: ${index} - ${message}`;
64             let step = logger[index];
65
66             assert(step.type, 'fulfilled', msg);
67             assert(step.value, expectedValue, msg);
68             assert(step.done, true, msg);
69
70             index++;
71             return this;
72         };
73
74         this.rejected = function (error, message = 'on reject') {
75             isNotOutOfLength();
76
77             const msg = `step: ${index} - ${message}`;
78             let step = logger[index];
79
80             assert(step.type, 'reject', msg);
81             assert(step.value, error.toString(), msg);
82             assert(step.done, true, msg);
83
84             index++;
85             return this;
86         };
87
88         this.catched = function (expectedError, message = 'on catch') {
89             isNotOutOfLength();
90
91             const msg = `step: ${index} - ${message}`;
92             let step = logger[index];
93
94             assert(step.type, 'catch', msg);
95             assert(step.value, expectedError, msg);
96             assert(step.done, true, msg);
97
98             index++;
99             return this;
100         };
101
102         this.custom = function (expectedValue, message = 'on custom event') {
103
104             const msg = `step: ${index} - ${message}`;
105             let step = logger[index];
106
107             assert(step.type, 'custom', msg);
108             assert(step.value, expectedValue, msg);
109             assert(step.done, false, msg);
110
111             index++;
112             return this;
113         };
114
115         this.isFinal = function (message = '') {
116             assert(index, logger.length, `expected final step: ${message}`);
117         }; 
118     }; 
119     
120     return new _assertLogger();
121 };
122
123 const getPromise = promiseHolder => {
124     return new Promise((resolve, reject) => {
125         promiseHolder.resolve = resolve;
126         promiseHolder.reject = reject;
127     });
128 };
129
130 var logger = new Logger();
131 const someValue = 'some-value';
132 const errorMessage = 'error-message';
133
134 async function * foo(value) {
135   let re = yield '1:' + value;
136   re = yield '2:' + re;
137   re = yield '3:' + re;
138   return 'end foo:' + re;
139 }
140
141 async function * boo(value) {
142   let reply = yield '0:' + value;
143   reply = yield* foo(reply);
144   yield '4:' + reply;
145 }
146
147 var b = boo('init');
148
149 b.next('0').then(fulfillSpy(logger));
150 b.next('1').then(fulfillSpy(logger));
151 b.next('2').then(fulfillSpy(logger));
152 b.next('3').then(fulfillSpy(logger));
153 b.next('4').then(fulfillSpy(logger));
154 b.next('5').then(fulfillSpy(logger));
155
156 drainMicrotasks();
157
158 assertLogger(logger)
159     .fullfilled('0:init')
160     .fullfilled('1:1')
161     .fullfilled('2:2')
162     .fullfilled('3:3')
163     .fullfilled('4:end foo:4')
164     .fullfilledDone(undefined)
165     .isFinal();
166
167 logger.clear();
168 var b2 = boo(':value');
169
170 b2.next(':0').then(fulfillSpy(logger));
171 b2.next(':1').then(fulfillSpy(logger), rejectSpy(logger));
172 b2.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
173 b2.next(':2').then(fulfillSpy(logger));
174 b2.next(':3').then(fulfillSpy(logger));
175 b2.next(':4').then(fulfillSpy(logger));
176
177 drainMicrotasks();
178
179 assertLogger(logger)
180     .fullfilled('0::value')
181     .fullfilled('1::1')
182     .fullfilledDone(someValue)
183     .fullfilledDone(undefined)
184     .fullfilledDone(undefined)
185     .fullfilledDone(undefined)
186     .isFinal();
187
188 logger.clear();
189 var b2 = boo('#value');
190
191 b2.next('#0').then(fulfillSpy(logger), rejectSpy(logger));
192 b2.next('#1').then(fulfillSpy(logger), rejectSpy(logger));
193 b2.next('#2').then(fulfillSpy(logger), rejectSpy(logger));
194 b2.throw(new Error(errorMessage)).then(fulfillSpy(logger), rejectSpy(logger));
195 b2.next('#3').then(fulfillSpy(logger), rejectSpy(logger));
196 b2.next('#4').then(fulfillSpy(logger), rejectSpy(logger));
197
198 drainMicrotasks();
199
200 assertLogger(logger)
201     .fullfilled('0:#value')
202     .fullfilled('1:#1')
203     .fullfilled('2:#2')
204     .rejected(new Error(errorMessage))
205     .fullfilledDone(undefined)
206     .fullfilledDone(undefined)
207     .isFinal();
208
209 async function * bar() {
210   yield '1';
211   yield '2';
212   throw new Error(errorMessage);
213   yield '3';
214   return 'end foo';
215 }
216
217 async function * baz() {
218   yield '0';
219   yield* bar();
220   yield '4';
221 }
222
223 logger.clear();
224 var bz1 = baz();
225
226 bz1.next().then(fulfillSpy(logger), rejectSpy(logger));
227 bz1.next().then(fulfillSpy(logger), rejectSpy(logger));
228 bz1.next().then(fulfillSpy(logger), rejectSpy(logger));
229 bz1.next().then(fulfillSpy(logger), rejectSpy(logger));
230 bz1.next().then(fulfillSpy(logger), rejectSpy(logger));
231
232 drainMicrotasks();
233
234 assertLogger(logger)
235     .fullfilled('0')
236     .fullfilled('1')
237     .fullfilled('2')
238     .rejected(new Error(errorMessage))
239     .fullfilledDone(undefined)
240     .isFinal();
241
242 logger.clear();
243 let promiseHolder = {};
244
245 async function *joo() {
246     yield '1';
247     yield getPromise(promiseHolder);
248 }
249
250 async function *goo () {
251     yield '0';
252     yield* joo();
253     yield '3';
254 }
255
256 let g = goo();
257
258 g.next().then(fulfillSpy(logger), rejectSpy(logger));
259 g.next().then(fulfillSpy(logger), rejectSpy(logger));
260 g.next().then(fulfillSpy(logger), rejectSpy(logger));
261 g.next().then(fulfillSpy(logger), rejectSpy(logger));
262 g.next().then(fulfillSpy(logger), rejectSpy(logger));
263
264 drainMicrotasks();
265
266 assertLogger(logger)
267     .fullfilled('0')
268     .fullfilled('1')
269     .isFinal();
270
271 promiseHolder.resolve('2');
272
273 drainMicrotasks();
274
275 assertLogger(logger)
276     .fullfilled('0')
277     .fullfilled('1')
278     .fullfilled('2')
279     .fullfilled('3')
280     .fullfilledDone(undefined)
281     .isFinal();
282
283 logger.clear();
284
285 g = goo();
286
287 g.next().then(fulfillSpy(logger), rejectSpy(logger));
288 g.next().then(fulfillSpy(logger), rejectSpy(logger));
289 g.next().then(fulfillSpy(logger), rejectSpy(logger));
290 g.next().then(fulfillSpy(logger), rejectSpy(logger));
291 g.next().then(fulfillSpy(logger), rejectSpy(logger));
292
293 drainMicrotasks();
294
295 assertLogger(logger)
296     .fullfilled('0')
297     .fullfilled('1')
298     .isFinal();
299
300 promiseHolder.reject('#2');
301
302 drainMicrotasks();
303
304 assertLogger(logger)
305     .fullfilled('0')
306     .fullfilled('1')
307     .rejected('#2')
308     .fullfilledDone(undefined)
309     .fullfilledDone(undefined)
310     .isFinal();
311
312 logger.clear();
313
314 g = goo();
315
316 g.next().then(fulfillSpy(logger), rejectSpy(logger));
317 g.next().then(fulfillSpy(logger), rejectSpy(logger));
318 g.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
319 g.next().then(fulfillSpy(logger), rejectSpy(logger));
320 g.next().then(fulfillSpy(logger), rejectSpy(logger));
321
322 drainMicrotasks();
323
324 assertLogger(logger)
325     .fullfilled('0')
326     .fullfilled('1')
327     .fullfilledDone(someValue)
328     .fullfilledDone(undefined)
329     .fullfilledDone(undefined)
330     .isFinal();
331
332 logger.clear();
333
334 g = goo();
335
336 g.next().then(fulfillSpy(logger), rejectSpy(logger));
337 g.next().then(fulfillSpy(logger), rejectSpy(logger));
338 g.next().then(fulfillSpy(logger), rejectSpy(logger));
339 g.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
340 g.next().then(fulfillSpy(logger), rejectSpy(logger));
341 g.next().then(fulfillSpy(logger), rejectSpy(logger));
342
343 drainMicrotasks();
344
345 assertLogger(logger)
346     .fullfilled('0')
347     .fullfilled('1')
348     .isFinal();
349
350 promiseHolder.resolve('#2');
351
352 drainMicrotasks();
353
354 assertLogger(logger)
355     .fullfilled('0')
356     .fullfilled('1')
357     .fullfilled('#2')
358     .fullfilledDone(someValue)
359     .fullfilledDone(undefined)
360     .fullfilledDone(undefined)
361     .isFinal();
362
363 logger.clear();
364
365 g = goo();
366
367 g.next().then(fulfillSpy(logger), rejectSpy(logger));
368 g.next().then(fulfillSpy(logger), rejectSpy(logger));
369 g.next().then(fulfillSpy(logger), rejectSpy(logger));
370 g.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
371 g.next().then(fulfillSpy(logger), rejectSpy(logger));
372 g.next().then(fulfillSpy(logger), rejectSpy(logger));
373
374 drainMicrotasks();
375
376 assertLogger(logger)
377     .fullfilled('0')
378     .fullfilled('1')
379     .isFinal();
380
381 promiseHolder.reject('#2');
382
383 drainMicrotasks();
384
385 assertLogger(logger)
386     .fullfilled('0')
387     .fullfilled('1')
388     .rejected('#2')
389     .fullfilledDone(someValue)
390     .fullfilledDone(undefined)
391     .fullfilledDone(undefined)
392     .isFinal();
393
394 logger.clear();
395 g = goo();
396
397 g.next().then(fulfillSpy(logger), rejectSpy(logger));
398 g.next().then(fulfillSpy(logger), rejectSpy(logger));
399 g.throw(new Error(errorMessage)).then(fulfillSpy(logger), rejectSpy(logger));
400 g.next().then(fulfillSpy(logger), rejectSpy(logger));
401 g.next().then(fulfillSpy(logger), rejectSpy(logger));
402
403 drainMicrotasks();
404
405 assertLogger(logger)
406     .fullfilled('0')
407     .fullfilled('1')
408     .rejected(new Error(errorMessage))
409     .fullfilledDone(undefined)
410     .fullfilledDone(undefined)
411     .isFinal();
412
413 promiseHolder.resolve('#2');
414
415 drainMicrotasks();
416
417 assertLogger(logger)
418     .fullfilled('0')
419     .fullfilled('1')
420     .rejected(new Error(errorMessage))
421     .fullfilledDone(undefined)
422     .fullfilledDone(undefined)
423     .isFinal();
424
425 logger.clear();
426 g = goo();
427
428 g.next().then(fulfillSpy(logger), rejectSpy(logger));
429 g.next().then(fulfillSpy(logger), rejectSpy(logger));
430 g.next().then(fulfillSpy(logger), rejectSpy(logger));
431 g.throw(new Error(errorMessage)).then(fulfillSpy(logger), rejectSpy(logger));
432 g.next().then(fulfillSpy(logger), rejectSpy(logger));
433 g.next().then(fulfillSpy(logger), rejectSpy(logger));
434
435 drainMicrotasks();
436
437 assertLogger(logger)
438     .fullfilled('0')
439     .fullfilled('1')
440     .isFinal();
441
442 promiseHolder.resolve('#2');
443
444 drainMicrotasks();
445
446 assertLogger(logger)
447     .fullfilled('0')
448     .fullfilled('1')
449     .fullfilled('#2')
450     .rejected(new Error(errorMessage))
451     .fullfilledDone(undefined)
452     .fullfilledDone(undefined)
453     .isFinal();
454
455 logger.clear();
456
457 g = goo();
458
459 g.next().then(fulfillSpy(logger), rejectSpy(logger));
460 g.next().then(fulfillSpy(logger), rejectSpy(logger));
461 g.next().then(fulfillSpy(logger), rejectSpy(logger));
462 g.throw(new Error(errorMessage)).then(fulfillSpy(logger), rejectSpy(logger));
463 g.next().then(fulfillSpy(logger), rejectSpy(logger));
464 g.next().then(fulfillSpy(logger), rejectSpy(logger));
465
466 drainMicrotasks();
467
468 assertLogger(logger)
469     .fullfilled('0')
470     .fullfilled('1')
471     .isFinal();
472
473 promiseHolder.reject('#2');
474
475 drainMicrotasks();
476
477 assertLogger(logger)
478     .fullfilled('0')
479     .fullfilled('1')
480     .rejected('#2')
481     .rejected(new Error(errorMessage))
482     .fullfilledDone(undefined)
483     .fullfilledDone(undefined)
484     .isFinal();
485
486 logger.clear();
487
488 async function *koo() {
489     yield '1';
490     await getPromise(promiseHolder);
491 }
492
493 async function *loo () {
494     yield '0';
495     yield* joo();
496     yield '3';
497 }
498
499 let l = loo();
500
501 l.next().then(fulfillSpy(logger), rejectSpy(logger));
502 l.next().then(fulfillSpy(logger), rejectSpy(logger));
503 l.next().then(fulfillSpy(logger), rejectSpy(logger));
504 l.next().then(fulfillSpy(logger), rejectSpy(logger));
505 l.next().then(fulfillSpy(logger), rejectSpy(logger));
506
507 drainMicrotasks();
508
509  assertLogger(logger)
510     .fullfilled("0")
511     .fullfilled("1")
512     .isFinal();
513
514 promiseHolder.resolve('#2');
515
516 drainMicrotasks();
517
518 assertLogger(logger)
519     .fullfilled('0')
520     .fullfilled('1')
521     .fullfilled('#2')
522     .fullfilled("3")
523     .fullfilledDone(undefined)
524     .isFinal();
525
526 logger.clear();
527 l = loo();
528
529 l.next().then(fulfillSpy(logger), rejectSpy(logger));
530 l.next().then(fulfillSpy(logger), rejectSpy(logger));
531 l.next().then(fulfillSpy(logger), rejectSpy(logger));
532 l.next().then(fulfillSpy(logger), rejectSpy(logger));
533 l.next().then(fulfillSpy(logger), rejectSpy(logger));
534
535 drainMicrotasks();
536
537 assertLogger(logger)
538     .fullfilled("0")
539     .fullfilled("1")
540     .isFinal();
541
542 promiseHolder.reject('#2');
543
544 drainMicrotasks();
545
546 assertLogger(logger)
547     .fullfilled('0')
548     .fullfilled('1')
549     .rejected('#2')
550     .fullfilledDone(undefined)
551     .fullfilledDone(undefined)
552     .isFinal();
553
554 logger.clear();
555
556 let asyncIter = {
557     [Symbol.asyncIterator]() { return this; },
558     next (value) {
559         customSpy(logger)('next:' + value);
560         return { value: value, done: 'iter:Finish' === value };
561     },
562     throw (error) {
563         customSpy(logger)('throw:' + error);
564         return error;
565     },
566     return(value) {
567         customSpy(logger)('return:' + value);
568         return { value: value, done: true };
569     }
570   };
571
572 async function *moo () {
573     yield '0';
574     yield* asyncIter;
575     yield '3';
576 }
577
578 let m = moo('Init');
579
580 m.next('A').then(fulfillSpy(logger), rejectSpy(logger));
581 m.next('B').then(fulfillSpy(logger), rejectSpy(logger));
582 m.next('C').then(fulfillSpy(logger), rejectSpy(logger));
583 m.next('D').then(fulfillSpy(logger), rejectSpy(logger));
584 m.next('E').then(fulfillSpy(logger), rejectSpy(logger));
585 m.next('iter:Finish').then(fulfillSpy(logger), rejectSpy(logger));
586 m.next('Finish').then(fulfillSpy(logger), rejectSpy(logger));
587
588 drainMicrotasks();
589
590 assertLogger(logger)
591     .custom('next:undefined')
592     .fullfilled('0')
593     .custom('next:C')
594     .fullfilled(undefined)
595     .custom('next:D')
596     .fullfilled('C')
597     .custom('next:E')
598     .fullfilled('D')
599     .custom('next:iter:Finish')
600     .fullfilled('E')
601     .fullfilled('3')
602     .fullfilledDone(undefined)
603     .isFinal();
604
605 logger.clear();
606
607 m = moo('Init');
608
609 m.next('A').then(fulfillSpy(logger), rejectSpy(logger));
610 m.next('B').then(fulfillSpy(logger), rejectSpy(logger));
611 m.return('C').then(fulfillSpy(logger), rejectSpy(logger));
612 m.next('D').then(fulfillSpy(logger), rejectSpy(logger));
613 m.next('E').then(fulfillSpy(logger), rejectSpy(logger));
614 m.next('iter:Finish').then(fulfillSpy(logger), rejectSpy(logger));
615 m.next('Finish').then(fulfillSpy(logger), rejectSpy(logger));
616
617 drainMicrotasks();
618
619 assertLogger(logger)
620     .custom('next:undefined')
621     .fullfilled('0')
622     .custom('return:C')
623     .fullfilled(undefined)
624     .fullfilledDone('C')
625     .fullfilledDone(undefined)
626     .fullfilledDone(undefined)
627     .fullfilledDone(undefined)
628     .fullfilledDone(undefined)
629     .isFinal();
630
631 logger.clear();
632
633 m = moo('Init');
634
635 m.next('A').then(fulfillSpy(logger), rejectSpy(logger));
636 m.next('B').then(fulfillSpy(logger), rejectSpy(logger));
637 m.throw(new Error(errorMessage)).then(fulfillSpy(logger), rejectSpy(logger));
638 m.next('D').then(fulfillSpy(logger), rejectSpy(logger));
639 m.next('E').then(fulfillSpy(logger), rejectSpy(logger));
640 m.next('iter:Finish').then(fulfillSpy(logger), rejectSpy(logger));
641 m.next('Finish').then(fulfillSpy(logger), rejectSpy(logger));
642
643 drainMicrotasks();
644
645 assertLogger(logger)
646     .custom('next:undefined')
647     .fullfilled('0')
648     .custom('throw:' + new Error(errorMessage))
649     .fullfilled(undefined)
650     .custom('next:D')
651     .fullfilled(undefined)
652     .custom('next:E')
653     .fullfilled('D')
654     .custom('next:iter:Finish')
655     .fullfilled('E')
656     .fullfilled('3')
657     .fullfilledDone(undefined)
658     .isFinal();
659
660 logger.clear();
661
662 async function* noo() {
663   try {
664     await Promise.reject("doop");
665   } finally {
666     yield* [1, 2, 3]; // Is this line reachable in this implementation?
667   }
668 }
669
670 const n = noo();
671
672 n.next().then(fulfillSpy(logger), rejectSpy(logger));
673 n.next().then(fulfillSpy(logger), rejectSpy(logger));
674 n.next().then(fulfillSpy(logger), rejectSpy(logger));
675 n.next().then(fulfillSpy(logger), rejectSpy(logger));
676 n.next().then(fulfillSpy(logger), rejectSpy(logger));
677
678 drainMicrotasks();
679
680 assertLogger(logger)
681     .fullfilled(1)
682     .fullfilled(2)
683     .fullfilled(3)
684     .rejected('doop');