• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16class Test {
17    private static UNSET: int = 0;
18    private static SUCCESS: int = 1;
19    private static FAIL: int = 2;
20
21    constructor(iterations: int = 0) {
22        this.result = Test.UNSET;
23        this.iterations = iterations;
24    }
25
26    success(): void {
27        if (this.result == Test.UNSET) {
28            this.result = Test.SUCCESS;
29        }
30    }
31
32    fail(): void {
33        this.result = Test.FAIL;
34        console.println("Test failed");
35        throw new Error();
36    }
37
38    check(): void {
39        if (this.result == Test.SUCCESS) {
40            return;
41        }
42        if (this.result == Test.UNSET) {
43            console.println("Test result is not set");
44        }
45        throw new Error();
46    }
47
48    is_unset(): boolean {
49        return (this.result == Test.UNSET);
50    }
51
52    ready(): boolean {
53        if (this.iterations == 0) {
54            return true;
55        }
56        this.iterations--;
57        return false;
58    }
59
60    static FATAL: int = 0;
61    static ERROR: int = 1;
62    static INFO: int = 2;
63    // private log_level: int = 5;
64    private log_level: int = 1;
65
66    setLogLevel(lvl: int): void {
67        this.log_level = lvl;
68    }
69
70    msg(s: String, lvl: int): void {
71        if (lvl <= this.log_level) {
72            console.println(s);
73        }
74    }
75
76    private result: int;
77    private iterations: int;
78}
79let globalTest: Test | null = null;
80
81function check(): int {
82    globalTest!.check();
83    return 0;
84}
85
86function is_unset(): boolean {
87    return globalTest!.is_unset();
88}
89
90function ready(): boolean {
91    return globalTest!.ready();
92}
93
94function testPendingPromise(): int {
95    globalTest = new Test();
96    let p = new Promise<Object>((resolve: (value: Object) => void): void => {
97        globalTest!.success()
98    });
99    globalTest!.check();
100    p.then<void>((): void => {
101        globalTest!.fail();
102    });
103    p.catch<void>((error: NullishType): void => {
104        globalTest!.fail();
105    });
106    // Check callback are not called inside 'then' and 'catch'
107    globalTest!.check();
108    return 0;
109}
110
111function testResolvedPromise(): int {
112    let obj = new Object();
113    let p = new Promise<Object>((resolve: (value: Object) => void): void => {
114        resolve(obj);
115    });
116    globalTest = new Test();
117    p.then<Object | null>((value: Object): Object | null => {
118        if (value == obj) {
119            globalTest!.success();
120        } else {
121            globalTest!.fail();
122        }
123        return null;
124    });
125    p.catch<Object | null>((err: NullishType): Object | null => {
126        globalTest!.fail();
127        return null;
128    });
129    return 0;
130}
131
132function testRejectedPromise(): int {
133    globalTest = new Test();
134    let error = new Error();
135    try {
136        let p = new Promise<Object>((resolve: (value: Object) => void): void => {
137            throw error;
138        });
139        p.then<Object | null>((value: Object): Object | null => {
140            globalTest!.fail();
141            return null;
142        });
143        p.catch<Object | null>((err: Error): Object => {
144            if (err == error) {
145                globalTest!.success();
146            } else {
147                globalTest!.fail();
148            }
149        });
150    } catch (e: Exception) {
151        globalTest!.fail();
152    }
153    return 0;
154}
155
156class ThenBeforeResolveFixture {
157    public fn: (value: Object) => void = (value: Object) => {};
158    public state = 0;
159}
160
161function testThenBeforeResolve(): int {
162    globalTest = new Test();
163    let fixture = new ThenBeforeResolveFixture();
164    let p = new Promise<Object>((resolve: (value: Object) => void): void => {
165        fixture.fn = resolve;
166    });
167    let obj = new Object();
168    p.then<Object | null>((value: Object): Object | null => {
169        if (value == obj) {
170            if (fixture.state == 0) {
171                fixture.state = 1;
172            } else {
173                console.println("Wrong 'then' call order");
174                globalTest!.fail();
175            }
176        } else {
177            console.println("Then is called with wrong object");
178            globalTest!.fail();
179        }
180        return null;
181    });
182    p.then<Object | null>((value: Object): Object | null => {
183        if (value == obj) {
184            if (fixture.state == 1) {
185                globalTest!.success();
186            } else {
187                console.println("Wrong 'then' call order");
188                globalTest!.fail();
189            }
190        } else {
191            console.println("Then is called with wrong object");
192            globalTest!.fail();
193        }
194        return null;
195    });
196    fixture.fn(obj);
197    return 0;
198}
199
200function testPromiseEmptyThen(): int {
201    globalTest = new Test();
202    let p = new Promise<Object>((resolve: (value: Object) => void): void => {
203        resolve(new Object());
204    });
205    let nextP = p.then<Object>((): Object => {
206        globalTest!.success();
207    });
208    return 0;
209}
210
211class PromiseChainFixture {
212    public state = 0;
213}
214
215function testPromiseChain(): int {
216    globalTest = new Test();
217    let fixture = new PromiseChainFixture();
218    let p = new Promise<Object>((resolve: (value: Object) => void): void => {
219        resolve(new Object());
220    });
221    // NOTE(audovichenko): Remove p1 and p2 variables #17359
222    let p1: Promise<void> = p.then<void>((): void => {
223        if (fixture.state == 0) {
224            fixture.state = 1;
225        } else {
226            globalTest!.fail();
227        }
228    });
229    let p2: Promise<void> = p1.then<void>((): void => {
230        if (fixture.state == 1) {
231            fixture.state = 2;
232        } else {
233            globalTest!.fail();
234        }
235    });
236    p2.then<void>((): void => {
237        if (fixture.state == 2) {
238            globalTest!.success();
239        } else {
240            globalTest!.fail();
241        }
242    });
243    return 0;
244}
245
246function testPromiseCatchFinallyChain(): int {
247    globalTest = new Test();
248    let fixture = new PromiseChainFixture();
249    let p: Promise<Object> = Promise.reject<Object>(new Error());
250    // NOTE(audovichenko): Remove p1 and p2 variables #17359
251    let p1: Promise<void> = p.then<void>((v: Object): void => {
252        globalTest!.fail();
253    });
254    let p2: Promise<void> = p1.catch<void>((value: Error): void => {
255        if (fixture.state == 0) {
256            fixture.state = 1;
257        } else {
258            globalTest!.fail();
259        }
260    });
261    p2.finally((): void => {
262        if (fixture.state == 1) {
263            globalTest!.success();
264        } else {
265            globalTest!.fail();
266        }
267    });
268    return 0;
269}
270
271function testResolvePromiseThenFinally(): int {
272    globalTest = new Test();
273    let fixture = new PromiseChainFixture();
274    let p = Promise.resolve<Object>(new Object());
275    // NOTE(audovichenko): Remove p1 and p2 variables #17359
276    let p1: Promise<void> = p.then<void, void>((value: Object): void => {
277        if (fixture.state == 0) {
278            fixture.state = 1;
279        } else {
280            globalTest!.fail();
281        }
282    }, (error: NullishType): void => {
283        globalTest!.fail();
284    });
285    p1.finally((): void => {
286        if (fixture.state == 1) {
287            globalTest!.success();
288        } else {
289            globalTest!.fail();
290        }
291    });
292    return 0;
293}
294
295function testRejectPromiseThenFinally(): int {
296    globalTest = new Test();
297    let fixture = new PromiseChainFixture();
298    let p = Promise.reject<Object>(new Error());
299    // NOTE(audovichenko): Remove p1 and p2 variables #17359
300    let p1: Promise<void> = p.then<void, void>((value: Object): void => {
301        globalTest!.fail();
302    }, (error: Error): void => {
303        if (fixture.state == 0) {
304            fixture.state = 1;
305        } else {
306            globalTest!.fail();
307        }
308    });
309    p1.finally((): void => {
310        if (fixture.state == 1) {
311            globalTest!.success();
312        } else {
313            globalTest!.fail();
314        }
315    });
316    return 0;
317}
318
319function testReturnPromise(): Promise<Object> {
320    return new Promise<Object>((resolve: (value: Object) => void): void => {
321        resolve("Panda");
322    });
323}
324
325async function testReturnPromiseFromAsync(): Promise<Object> {
326    return new Promise<Object>((resolve: (value: Object) => void): void => {
327        resolve("Panda");
328    });
329}
330
331let resolvePromiseFn: ((value: Object) => void) | null = null;
332
333function testReturnPendingPromise(): Promise<Object> {
334    return new Promise<Object>((resolve: (value: Object) => void): void => {
335        resolvePromiseFn = resolve;
336    });
337}
338
339function resolvePendingPromise(): boolean {
340    if (resolvePromiseFn == null) {
341        return false;
342    }
343    (resolvePromiseFn as (value: Object) => void)("Panda");
344    return true;
345}
346
347let unresolved1: Object | null = null;
348let unresolved2: Object | null = null;
349let unresolved3: Object | null = null;
350
351async function asyncFuncAwait(): Promise<Object | null> {
352    let promise: Promise<Object> = new Promise<Object>((resolve: (obj: Object) => void): void => {
353        resolve("resolved");
354    });
355    unresolved1 = await promise;
356    return null;
357}
358
359let asyncLambdaAwait: () => Promise<Object | null> = async (): Promise<Object | null> => {
360    let promise: Promise<Object> = new Promise<Object>((resolve: (obj: Object) => void): void => {
361        resolve("resolved");
362    });
363    unresolved2 = await promise;
364    return null;
365}
366
367async function RejPromise1(): Promise<string> {
368    let s: string = await new Promise<string>(
369        (resolve: (obj: string|PromiseLike<string>) => void,
370         reject: (obj: Error) => void): void => {
371             reject(new Error("rejected"));
372    });
373    return s;
374}
375
376async function RejPromise2(): Promise<string> {
377    return await RejPromise1();
378}
379
380async function asyncFuncAwaitRejected(): Promise<Object | null> {
381    let promise: Promise<string> = RejPromise2();
382
383    let promise2: Promise<string> =
384    promise.then((x: string|Promise<string>): string => {
385        return "smth";
386    })
387
388    try {
389        unresolved3 = await promise;
390        globalTest!.fail();
391    } catch (e) {
392        return null;
393    }
394    globalTest!.fail();
395    return null;
396}
397
398function testAwaitPromise(): int {
399    globalTest = new Test();
400    let p1: Promise<Object | null> = asyncFuncAwait();
401    let p2: Promise<Object | null> = asyncLambdaAwait();
402    let p3: Promise<Object | null> = asyncFuncAwaitRejected();
403    // execute async func (post await part) before check
404    await Promise.all([p1, p2, p3]);
405    if (unresolved1 != "resolved" || unresolved2 != "resolved") {
406        globalTest!.fail();
407    }
408    globalTest!.success();
409    return 0;
410}
411
412function makeResolvedPromise(v: String): Promise<Object> {
413    return new Promise<Object>((resolve: (value: Object) => void): void => {
414        resolve(v);
415    });
416}
417
418async function testAwaitJsPromiseSimple(p: Promise<Object>): Promise<void> {
419    let res: String = (await p) as String;
420}
421
422async function testAwaitJsPromise(pendingP: Promise<Object>): Promise<Object> {
423    globalTest = new Test();
424
425    globalTest!.msg("testAwaitJsPromise: start", Test.INFO);
426    let res: String = (await pendingP) as String;
427
428    globalTest!.msg("testAwaitJsPromise: await result is: " + res, Test.INFO);
429
430    if (res != "JS_PROMISE_RESULT") {
431        globalTest!.msg("testAwaitJsPromise: await result is wrong!", Test.FATAL);
432        globalTest!.fail();
433    } else {
434        globalTest!.msg("testAwaitJsPromise: await result is CORRECT!", Test.INFO);
435        globalTest!.success();
436    }
437
438    globalTest!.msg("testAwaitJsPromise: done", Test.INFO);
439    /**
440     * NOTE(konstanting, #IAD5MH): add a test where we would return here a PENDING promise.
441     * Currently this leads to a crash, because:
442     *     - testAwaitJsPromise$asyncImpl resolves its linked promise (P1) with makeResolvedPromise's result (P2)
443     *     - since we returned P1 to JS as PENDING (due to await presence), it has listeners
444     *     - thus, P1 resolution triggers PandaEtsVM::FirePromiseStateChanged, which acquires promise_listeners_lock_
445     *     - this leads to wrapping P1's resolution value (P2) into a JS promise
446     *     - and since P2 is still PENDING, we must add a listener to it in order to notify JS of its resolution later on
447     *     - this triggers PandaEtsVM::AddPromiseListener, which acquires already acquired promise_listeners_lock_ within
448     *       the same thread
449     *     - BOOM! Assertion fires.
450     */
451    return makeResolvedPromise("Panda");
452}
453
454async function testAsyncBoolean(): Promise<boolean> {
455    return true;
456}
457
458async function testAsyncByte(): Promise<byte> {
459    let x: byte = 127;
460    return x;
461}
462
463async function testAsyncChar(): Promise<char> {
464    return c'x';
465}
466
467async function testAsyncShort(): Promise<short> {
468    let x: short = 32767;
469    return x;
470}
471
472async function testAsyncInt(): Promise<int> {
473    return 5;
474}
475
476async function testAsyncLong(): Promise<long> {
477    return Long.MAX_VALUE;
478}
479
480async function testAsyncFloat(): Promise<float> {
481    let x: float = 3.14;
482    return x;
483}
484
485async function testAsyncDouble(): Promise<double> {
486    return 3.2;
487}
488
489async function testAsyncString(): Promise<String> {
490    return "Panda";
491}
492
493async function testAsyncVoid(): Promise<void> { return undefined }
494async function testAsyncVoidEmpty(): Promise<void> {}
495async function testAsyncVoidNothing() {}
496
497function testPromiseAllEmpty(): void {
498    globalTest = new Test();
499    let promises: FixedArray<Promise<Object>> = [];
500    Promise.all<Object>(promises).then<void>((values: Array<Object>): void => {
501        if (values == null || values.length != 0) {
502            globalTest!.fail();
503        } else {
504            globalTest!.success();
505        }
506    });
507}
508
509function testPromiseAllResolved(): void {
510    globalTest = new Test();
511    let p1: Promise<Object> = Promise.resolve<Object>("abc");
512    let p2: Promise<Object> = Promise.resolve<Object>("def");
513    let p3: Promise<Object> = Promise.resolve<Object>("xyz");
514
515    Promise.all<Object>([
516        p1, p2, p3
517    ]).then<void>((values: Array<Object>): void => {
518        if (values.length != 3) {
519            globalTest!.fail();
520        }
521        if (values[0] != "abc") {
522            globalTest!.fail();
523        }
524        if (values[1] != "def") {
525            globalTest!.fail();
526        }
527        if (values[2] != "xyz") {
528            globalTest!.fail();
529        }
530        globalTest!.success();
531    });
532}
533
534function testPromiseAllRejected(): void {
535    globalTest = new Test();
536    let p1: Promise<Object> = Promise.resolve<Object>("abc");
537    let p2: Promise<Object> = Promise.reject<Object>(new Error("def"));
538    let p3: Promise<Object> = Promise.resolve<Object>("xyz");
539    Promise.all([
540        p1, p2, p3
541    ]).then<void, void>((v: Object): void => {
542        globalTest!.fail();
543    }, (err: Error): void => {
544        if (err.message != "def") {
545            globalTest!.fail();
546        } else {
547            globalTest!.success();
548        }
549    });
550}
551
552function testPromiseAllRawValues(): void {
553    globalTest = new Test();
554    let p1: Object = "abc";
555    let p2: Object = "def";
556    let p3: Object = "xyz";
557
558    Promise.all<Object>([
559        p1, p2, p3
560    ]).then<void>((values: Array<Object>): void => {
561        if (values.length != 3) {
562            globalTest!.fail();
563        }
564        if (values[0] != "abc") {
565            globalTest!.fail();
566        }
567        if (values[1] != "def") {
568            globalTest!.fail();
569        }
570        if (values[2] != "xyz") {
571            globalTest!.fail();
572        }
573        globalTest!.success();
574    });
575}
576
577function testPromiseAllIterable(): void {
578    globalTest = new Test();
579    let array = new Array<Object|PromiseLike<Object>>();
580    array.push(Promise.resolve<Object>("abc"));
581    array.push("def");
582    array.push(Promise.resolve<Object>("xyz"));
583
584    Promise.all<Object>(array).then<void>((values: Array<Object>): void => {
585        if (values.length != 3) {
586            globalTest!.fail();
587        }
588        if (values[0] != "abc") {
589            globalTest!.fail();
590        }
591        if (values[1] != "def") {
592            globalTest!.fail();
593        }
594        if (values[2] != "xyz") {
595            globalTest!.fail();
596        }
597        globalTest!.success();
598    });
599}
600
601function testPromiseAllSettledEmpty(): void {
602    globalTest = new Test();
603    let promises: FixedArray<Promise<Object>> = [];
604    Promise.allSettled<Object>(promises).then<void, void>((values: PromiseSettledResult<Object>[]): void => {
605        if (values.length != 0) {
606            globalTest!.fail();
607        }
608        globalTest!.success();
609    }, (err: Error): void => {
610        globalTest!.fail();
611    });
612}
613
614function testPromiseAllSettled(): void {
615    globalTest = new Test();
616    let p1: Promise<Object> = Promise.resolve<Object>("abc");
617    let p2: Promise<Object> = Promise.reject<Object>(new Error("def"));
618    let p3: Promise<Object> = Promise.resolve<Object>("xyz");
619    Promise.allSettled<Object>([
620        p1, p2, p3
621    ]).then<void, void>((result: PromiseSettledResult<Object>[]): void => {
622        if (result.length != 3) {
623            globalTest!.fail();
624        }
625        if (!(result[0] instanceof PromiseFulfilledResult)) {
626            globalTest!.fail();
627        }
628        let res0 = result[0] as PromiseFulfilledResult<Object>;
629        if (res0.status != PromiseStatus.fulfilled || res0.value != "abc") {
630            globalTest!.fail();
631        }
632        if (!(result[1] instanceof PromiseRejectedResult)) {
633            globalTest!.fail();
634        }
635        let res1 = result[1] as PromiseRejectedResult;
636        if (res1.status != PromiseStatus.rejected || res1.reason.message != "def") {
637            globalTest!.fail();
638        }
639        if (!(result[2] instanceof PromiseFulfilledResult)) {
640            globalTest!.fail();
641        }
642        let res2 = result[2] as PromiseFulfilledResult<Object>;
643        if (res2.status != PromiseStatus.fulfilled || res2.value != "xyz") {
644            globalTest!.fail();
645        }
646        globalTest!.success();
647    }, (err: Error): void => {
648        globalTest!.fail();
649    });
650}
651
652function testPromiseAnyEmpty(): void {
653    globalTest = new Test();
654    let promises: FixedArray<Promise<Object>> = [];
655    Promise.any(promises).then<void, void>((v: Object): void => {
656        globalTest!.fail();
657    }, (err: Error): void => {
658        if (err != null && err instanceof AggregateError) {
659            globalTest!.success();
660        } else {
661            globalTest!.fail();
662        }
663    });
664}
665
666function testPromiseAnyResolved(): void {
667    globalTest = new Test();
668    let p1: Promise<Object> = Promise.reject<Object>(new Error("abc"));
669    let p2: Promise<Object> = Promise.reject<Object>(new Error("def"));
670    let p3: Promise<Object> = Promise.resolve<Object>("xyz");
671    Promise.any([
672        p1, p2, p3
673    ]).then<void>((value: Object): void => {
674        if (value != "xyz") {
675            globalTest!.fail();
676        }
677        globalTest!.success();
678    });
679}
680
681function testPromiseAnyRejected(): void {
682    globalTest = new Test();
683    let p1: Promise<Object> = Promise.reject<Object>(new Error("abc"));
684    let p2: Promise<Object> = Promise.reject<Object>(new Error("def"));
685    let p3: Promise<Object> = Promise.reject<Object>(new Error("xyz"));
686    Promise.any([
687        p1, p2, p3
688    ]).then<void, void>((v: Object): void => {
689        globalTest!.fail();
690    }, (err: Error): void => {
691        if (err == null || !(err instanceof AggregateError)) {
692            globalTest!.fail();
693        } else {
694            globalTest!.success();
695        }
696    });
697}
698
699function testPromiseAnyRawValues(): void {
700    globalTest = new Test();
701    Promise.any([
702        "abc", "def", "xyz"
703    ]).then<void>((value: Object): void => {
704        if (value != "abc") {
705            globalTest!.fail();
706        }
707        globalTest!.success();
708    });
709}
710
711function testPromiseAnyIterable(): void {
712    globalTest = new Test();
713    let array = new Array<Object|PromiseLike<Object>>();
714    array.push(Promise.reject<Object>(new Error("def")));
715    array.push(Promise.resolve<Object>("xyz"));
716    Promise.any<Object>(array).then<void>((value: Object): void => {
717        if (value != "xyz") {
718            globalTest!.fail();
719        }
720        globalTest!.success();
721    });
722}
723
724function testPromiseRaceResolved(): void {
725    globalTest = new Test();
726    let p1: Promise<Object> = Promise.resolve<Object>("abc");
727    let p2: Promise<Object> = Promise.reject<Object>(new Error("def"));
728    Promise.race([
729        p1, p2
730    ]).then<void, void>((value: Object): void => {
731        if (value != "abc") {
732            globalTest!.fail();
733        }
734        globalTest!.success();
735    }, (error: Error): void => {
736        globalTest!.fail();
737    });
738}
739
740function testPromiseRaceRejected(): void {
741    globalTest = new Test();
742    let p1: Promise<Object> = Promise.reject<Object>(new Error("abc"));
743    let p2: Promise<Object> = Promise.resolve<Object>("def");
744    Promise.race([
745        p1, p2
746    ]).then<void, void>((value: Object): void => {
747        globalTest!.fail();
748    }, (error: Error): void => {
749        if (error.message != "abc") {
750            globalTest!.fail();
751        }
752        globalTest!.success();
753    });
754}
755
756function testPromiseThenOnRejection(): void {
757    globalTest = new Test();
758    Promise.reject<Error>(new Error("test")).then<void, string>(
759    (value: Object): void => {
760        globalTest!.fail();
761    }, (error: Error): string => {
762        return "correct flow";
763    }).then<string, void>((value): string => {
764        globalTest!.success();
765        return value as string
766    }, (error: Error): void => {
767        globalTest!.fail();
768    });
769}
770
771let promiseFixture: Promise<void>|null = null;
772
773function getPromise(): Promise<void> {
774    promiseFixture = Promise.resolve();
775    return promiseFixture!;
776}
777
778function setAndCheckPromise(p: Promise<void>): void {
779    globalTest = new Test();
780    if (promiseFixture == null) {
781        console.log("Promise is not set");
782        globalTest!.fail();
783    }
784    if (promiseFixture !== p) {
785        console.log("Expected the returned promise and the argument are the same but they differs");
786        globalTest!.fail();
787    }
788}
789
790function getTheSamePromise(p: Promise<void>): Promise<void> {
791    return p;
792}
793