• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "ecmascript/builtins/builtins_promise.h"
17 
18 #include "ecmascript/builtins/builtins_array.h"
19 #include "ecmascript/ecma_string.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/jobs/micro_job_queue.h"
23 #include "ecmascript/js_array.h"
24 #include "ecmascript/js_promise.h"
25 #include "ecmascript/js_tagged_value-inl.h"
26 #include "ecmascript/js_tagged_value.h"
27 #include "ecmascript/js_thread.h"
28 #include "ecmascript/object_factory.h"
29 #include "ecmascript/tests/test_helper.h"
30 
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::builtins;
33 
34 namespace panda::test {
35 using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
36 using JSArray = panda::ecmascript::JSArray;
37 
38 class BuiltinsPromiseTest : public BaseTestWithScope<false> {
39 };
40 
41 // native function for race2 then_on_rejected()
TestPromiseRaceThenOnRejectd(EcmaRuntimeCallInfo * argv)42 JSTaggedValue TestPromiseRaceThenOnRejectd(EcmaRuntimeCallInfo *argv)
43 {
44     JSThread *thread = argv->GetThread();
45     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
46     // 12345 : test case
47     EXPECT_EQ(JSTaggedValue::SameValue(thread, result.GetTaggedValue(), JSTaggedValue(12345)), true);
48     return JSTaggedValue::Undefined();
49 }
50 
51 // native function for all then_on_resolved()
TestPromiseAllThenOnResolved(EcmaRuntimeCallInfo * argv)52 JSTaggedValue TestPromiseAllThenOnResolved(EcmaRuntimeCallInfo *argv)
53 {
54     JSThread *thread = argv->GetThread();
55     JSHandle<JSTaggedValue> array = BuiltinsBase::GetCallArg(argv, 0);
56     JSHandle<JSObject> objectArray = JSHandle<JSObject>::Cast(array);
57     [[maybe_unused]] PropertyDescriptor desc(argv->GetThread());
58     [[maybe_unused]] bool result1 = JSObject::GetOwnProperty(
59         argv->GetThread(), objectArray, JSHandle<JSTaggedValue>(argv->GetThread(), JSTaggedValue(0)), desc);
60     EXPECT_TRUE(result1);
61     JSHandle<JSTaggedValue> value1 = desc.GetValue();
62     // 111 : test case
63     EXPECT_EQ(JSTaggedValue::SameValue(thread, value1.GetTaggedValue(), JSTaggedValue(111)), true);
64     [[maybe_unused]] bool result2 = JSObject::GetOwnProperty(
65         argv->GetThread(), objectArray, JSHandle<JSTaggedValue>(argv->GetThread(), JSTaggedValue(1)), desc);
66     EXPECT_TRUE(result2);
67     JSHandle<JSTaggedValue> value2 = desc.GetValue();
68     // 222 : test case
69     EXPECT_EQ(JSTaggedValue::SameValue(thread, value2.GetTaggedValue(), JSTaggedValue(222)), true);
70     return JSTaggedValue::Undefined();
71 }
72 
73 // native function for catch catch_on_rejected()
TestPromiseCatch(EcmaRuntimeCallInfo * argv)74 JSTaggedValue TestPromiseCatch(EcmaRuntimeCallInfo *argv)
75 {
76     JSThread *thread = argv->GetThread();
77     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
78     // 3 : test case
79     EXPECT_EQ(JSTaggedValue::SameValue(thread, result.GetTaggedValue(), JSTaggedValue(3)), true);
80     return JSTaggedValue::Undefined();
81 }
82 
83 // native function for then then_on_resolved()
TestPromiseThenOnResolved(EcmaRuntimeCallInfo * argv)84 JSTaggedValue TestPromiseThenOnResolved(EcmaRuntimeCallInfo *argv)
85 {
86     JSThread *thread = argv->GetThread();
87     auto factory = thread->GetEcmaVM()->GetFactory();
88     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
89     auto expect = factory->NewFromASCII("resolve");
90     EXPECT_EQ(JSTaggedValue::SameValue(thread, result.GetTaggedValue(), expect.GetTaggedValue()), true);
91     return JSTaggedValue::Undefined();
92 }
93 
94 // native function for then then_on_rejected()
TestPromiseThenOnRejected(EcmaRuntimeCallInfo * argv)95 JSTaggedValue TestPromiseThenOnRejected(EcmaRuntimeCallInfo *argv)
96 {
97     JSThread *thread = argv->GetThread();
98     auto factory = thread->GetEcmaVM()->GetFactory();
99     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
100     auto expect = factory->NewFromASCII("reject");
101     EXPECT_EQ(JSTaggedValue::SameValue(thread, result.GetTaggedValue(), expect.GetTaggedValue()), true);
102     return JSTaggedValue::Undefined();
103 }
104 
105 enum class AlgorithmType {
106     REJECT,
107     RESOLVE,
108     RACE,
109     ALL,
110 };
111 
PromiseAlgorithm(JSThread * thread,JSHandle<JSFunction> & promise,JSTaggedValue arg,AlgorithmType type)112 JSTaggedValue PromiseAlgorithm(JSThread *thread, JSHandle<JSFunction>& promise, JSTaggedValue arg,
113     AlgorithmType type)
114 {
115     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread,  JSTaggedValue(*promise), 6);
116     ecmaRuntimeCallInfo->SetFunction(promise.GetTaggedValue());
117     ecmaRuntimeCallInfo->SetThis(promise.GetTaggedValue());
118     ecmaRuntimeCallInfo->SetCallArg(0, arg);
119 
120     auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
121     JSTaggedValue result;
122     switch (type) {
123         case AlgorithmType::REJECT:
124             result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo);
125             break;
126         case AlgorithmType::RESOLVE:
127             result = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo);
128             break;
129         case AlgorithmType::RACE:
130             result = BuiltinsPromise::Race(ecmaRuntimeCallInfo);
131             break;
132         case AlgorithmType::ALL:
133             result = BuiltinsPromise::All(ecmaRuntimeCallInfo);
134             break;
135         default:
136             break;
137     }
138 
139     TestHelper::TearDownFrame(thread, prev);
140     return result;
141 }
142 
ThanAlgorithm(JSThread * thread,JSHandle<JSPromise> & promise,JSTaggedValue arg1,JSTaggedValue arg2)143 JSTaggedValue ThanAlgorithm(JSThread *thread, JSHandle<JSPromise>& promise, JSTaggedValue arg1,
144     JSTaggedValue arg2)
145 {
146     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread,  promise.GetTaggedValue(), 8);
147     ecmaRuntimeCallInfo->SetFunction(promise.GetTaggedValue());
148     ecmaRuntimeCallInfo->SetThis(promise.GetTaggedValue());
149     ecmaRuntimeCallInfo->SetCallArg(0, arg1);
150     ecmaRuntimeCallInfo->SetCallArg(1, arg2);
151     auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
152     auto result = BuiltinsPromise::Then(ecmaRuntimeCallInfo);
153     TestHelper::TearDownFrame(thread, prev);
154     return result;
155 }
156 /*
157  * @tc.name: Reject1
158  * @tc.desc: The reject method receives a number.
159  * @tc.type: FUNC
160  */
HWTEST_F_L0(BuiltinsPromiseTest,Reject1)161 HWTEST_F_L0(BuiltinsPromiseTest, Reject1)
162 {
163     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
164 
165     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
166     JSHandle<JSTaggedValue> paramMsg(thread, JSTaggedValue(3));
167 
168     // /**
169     //  * @tc.steps: var p1 = Promise.reject(3).
170     //  */
171 
172     auto result = PromiseAlgorithm(thread, promise, paramMsg.GetTaggedValue(), AlgorithmType::REJECT);
173     JSHandle<JSPromise> rejectPromise(thread, result);
174     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
175     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), JSTaggedValue(3)), true);
176 }
177 
178 /*
179  * @tc.name: Reject2
180  * @tc.desc: The reject method receives a promise object.
181  * @tc.type: FUNC
182  */
HWTEST_F_L0(BuiltinsPromiseTest,Reject2)183 HWTEST_F_L0(BuiltinsPromiseTest, Reject2)
184 {
185     ObjectFactory *factory = instance->GetFactory();
186     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
187 
188     // constructor promise1
189     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
190     JSHandle<JSTaggedValue> paramMsg1 =
191         JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("Promise reject"));
192 
193     /**
194      * @tc.steps: step1. var p1 = Promise.reject("Promise reject")
195      */
196     auto result = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::REJECT);
197     JSHandle<JSPromise> promise1(thread, result);
198     EXPECT_EQ(promise1->GetPromiseState(), PromiseState::REJECTED);
199     EXPECT_EQ(JSTaggedValue::SameValue(thread, promise1->GetPromiseResult(thread), paramMsg1.GetTaggedValue()), true);
200 
201     /**
202      * @tc.steps: step2. var p2 = Promise.reject(p1)
203      */
204     auto result1 = PromiseAlgorithm(thread, promise, promise1.GetTaggedValue(), AlgorithmType::REJECT);
205     JSHandle<JSPromise> promise2(thread, result1);
206     EXPECT_NE(*promise1, *promise2);
207     EXPECT_EQ(promise2->GetPromiseState(), PromiseState::REJECTED);
208     EXPECT_EQ(JSTaggedValue::SameValue(thread, promise2->GetPromiseResult(thread),
209                                        JSTaggedValue(promise1.GetTaggedValue().GetRawData())),
210               true);
211 }
212 
213 /*
214  * @tc.name: Resolve1
215  * @tc.desc: The resolve method receives a number.
216  * @tc.type: FUNC
217  */
HWTEST_F_L0(BuiltinsPromiseTest,Resolve1)218 HWTEST_F_L0(BuiltinsPromiseTest, Resolve1)
219 {
220     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
221 
222     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
223     JSHandle<JSTaggedValue> paramMsg(thread, JSTaggedValue(5));
224 
225     /**
226      * @tc.steps: step1. var p1 = Promise.resolve(12345)
227      */
228     auto result = PromiseAlgorithm(thread, promise, paramMsg.GetTaggedValue(), AlgorithmType::RESOLVE);
229     JSHandle<JSPromise> rejectPromise(thread, result);
230     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::FULFILLED);
231     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), JSTaggedValue(5)), true);
232 }
233 
234 /*
235  * @tc.name: Resolve2
236  * @tc.desc: The resolve method receives a promise object.
237  * @tc.type: FUNC
238  */
HWTEST_F_L0(BuiltinsPromiseTest,Resolve2)239 HWTEST_F_L0(BuiltinsPromiseTest, Resolve2)
240 {
241     ObjectFactory *factory = instance->GetFactory();
242     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
243 
244     // constructor promise1
245     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
246     JSHandle<JSTaggedValue> paramMsg1 =
247         JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("Promise reject"));
248 
249     /**
250      * @tc.steps: step1. var p1 = Promise.reject("Promise reject")
251      */
252     auto result = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::REJECT);
253     JSHandle<JSPromise> promise1(thread, result);
254     EXPECT_EQ(promise1->GetPromiseState(), PromiseState::REJECTED);
255     EXPECT_EQ(JSTaggedValue::SameValue(thread, promise1->GetPromiseResult(thread), paramMsg1.GetTaggedValue()), true);
256 
257     // promise1 Enter Reject() as a parameter.
258     /**
259      * @tc.steps: step2. var p2 = Promise.resolve(p1)
260      */
261     auto result1 = PromiseAlgorithm(thread, promise, promise1.GetTaggedValue(), AlgorithmType::RESOLVE);
262     JSHandle<JSPromise> promise2(thread, result1);
263     EXPECT_EQ(*promise1, *promise2);
264     EXPECT_EQ(promise2->GetPromiseState(), PromiseState::REJECTED);
265     EXPECT_EQ(JSTaggedValue::SameValue(thread, promise2->GetPromiseResult(thread), paramMsg1.GetTaggedValue()), true);
266 }
267 
268 /*
269  * @tc.name: Race1
270  * @tc.desc: The race method receives an array.
271  * @tc.type: FUNC
272  */
HWTEST_F_L0(BuiltinsPromiseTest,Race1)273 HWTEST_F_L0(BuiltinsPromiseTest, Race1)
274 {
275     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
276 
277     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
278     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(12345));
279 
280     /**
281      * @tc.steps: step1. var p1 = Promise.reject(12345)
282      */
283     auto result1 = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::REJECT);
284     JSHandle<JSPromise> rejectPromise(thread, result1);
285     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
286     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), JSTaggedValue(12345)), true);
287 
288     /**
289      * @tc.steps: step2. var p2 = Promise.resolve(6789)
290      */
291     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(6789));
292     auto result2 = PromiseAlgorithm(thread, promise, paramMsg2.GetTaggedValue(), AlgorithmType::RESOLVE);
293     JSHandle<JSPromise> resolvePromise(thread, result2);
294     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
295     EXPECT_EQ(JSTaggedValue::SameValue(thread, resolvePromise->GetPromiseResult(thread), JSTaggedValue(6789)), true);
296     /**
297      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
298      */
299     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
300     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(rejectPromise));
301     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
302 
303     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise));
304     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
305 
306     /**
307      * @tc.steps: step4. var p3 = Promise.race([p1,p2]);
308      */
309     auto result4 = PromiseAlgorithm(thread, promise, array.GetTaggedValue(), AlgorithmType::RACE);
310     JSHandle<JSPromise> racePromise(thread, result4);
311     EXPECT_EQ(racePromise->GetPromiseState(), PromiseState::PENDING);
312     EXPECT_EQ(racePromise->GetPromiseResult(thread).IsUndefined(), true);
313 }
314 
315 /*
316  * @tc.name: Race2
317  * @tc.desc: The Race method receives an array, uses the Then method to save the task in the task queue, and outputs
318  * the execution result of the queue.
319  * @tc.type: FUNC
320  */
HWTEST_F_L0(BuiltinsPromiseTest,Race2)321 HWTEST_F_L0(BuiltinsPromiseTest, Race2)
322 {
323     ObjectFactory *factory = instance->GetFactory();
324     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
325 
326     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
327     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(12345));
328     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(6789));
329 
330     /**
331      * @tc.steps: step1. var p1 = Promise.reject(12345)
332      */
333     auto result1 = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::REJECT);
334     JSHandle<JSPromise> rejectPromise(thread, result1);
335     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
336     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), JSTaggedValue(12345)), true);
337 
338     /**
339      * @tc.steps: step2. var p2 = Promise.resolve(6789)
340      */
341     auto result2 = PromiseAlgorithm(thread, promise, paramMsg2.GetTaggedValue(), AlgorithmType::RESOLVE);
342     JSHandle<JSPromise> resolvePromise(thread, result2);
343     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
344     EXPECT_EQ(JSTaggedValue::SameValue(thread, resolvePromise->GetPromiseResult(thread), JSTaggedValue(6789)), true);
345 
346     /**
347      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
348      */
349     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
350     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(rejectPromise));
351     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
352 
353     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise));
354     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
355 
356     /**
357      * @tc.steps: step4. var p3 = Promise.race([p1,p2]);
358      */
359     auto result3 = PromiseAlgorithm(thread, promise, array.GetTaggedValue(), AlgorithmType::RACE);
360     JSHandle<JSPromise> racePromise(thread, result3);
361     EXPECT_EQ(racePromise->GetPromiseState(), PromiseState::PENDING);
362     EXPECT_EQ(racePromise->GetPromiseResult(thread).IsUndefined(), true);
363 
364     /**
365      * @tc.steps: step5. p3.then((resolve)=>{print(resolve)}, (reject)=>{print(reject)})
366      */
367     JSHandle<JSFunction> raceThenOnRejected =
368         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseRaceThenOnRejectd));
369     auto thenResult = ThanAlgorithm(thread, racePromise, JSTaggedValue::Undefined(),
370                                     raceThenOnRejected.GetTaggedValue());
371     JSHandle<JSPromise> thenPromise(thread, thenResult);
372 
373     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
374     EXPECT_TRUE(thenPromise->GetPromiseResult(thread).IsUndefined());
375 
376     /**
377      * @tc.steps: step6. execute promise queue
378      */
379     auto microJobQueue = instance->GetMicroJobQueue();
380     if (!thread->HasPendingException()) {
381         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
382     }
383 }
384 
385 /*
386  * @tc.name: All
387  * @tc.desc: The All method receives an array, uses the Then method to save the task in the task queue, and outputs the
388  * execution result of the queue.
389  * @tc.type: FUNC
390  */
HWTEST_F_L0(BuiltinsPromiseTest,All)391 HWTEST_F_L0(BuiltinsPromiseTest, All)
392 {
393     ObjectFactory *factory = instance->GetFactory();
394     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
395 
396     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
397     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(111));
398     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(222));
399 
400     /**
401      * @tc.steps: step1. var p1 = Promise.resolve(111)
402      */
403     auto result1 = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::RESOLVE);
404     JSHandle<JSPromise> resolvePromise1(thread, result1);
405     EXPECT_EQ(resolvePromise1->GetPromiseState(), PromiseState::FULFILLED);
406     EXPECT_EQ(JSTaggedValue::SameValue(thread, resolvePromise1->GetPromiseResult(thread), JSTaggedValue(111)), true);
407 
408     /**
409      * @tc.steps: step2. var p2 = Promise.resolve(222)
410      */
411     auto result2 = PromiseAlgorithm(thread, promise, paramMsg2.GetTaggedValue(), AlgorithmType::RESOLVE);
412     JSHandle<JSPromise> resolvePromise2(thread, result2);
413     EXPECT_EQ(resolvePromise2->GetPromiseState(), PromiseState::FULFILLED);
414     EXPECT_EQ(JSTaggedValue::SameValue(thread, resolvePromise2->GetPromiseResult(thread), JSTaggedValue(222)), true);
415 
416     /**
417      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
418      */
419     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
420     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise1));
421     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
422 
423     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise2));
424     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
425 
426     /**
427      * @tc.steps: step4. var p3 = Promise.all([p1,p2]);
428      */
429     auto result4 = PromiseAlgorithm(thread, promise, array.GetTaggedValue(), AlgorithmType::ALL);
430     JSHandle<JSPromise> allPromise(thread, result4);
431     EXPECT_EQ(allPromise->GetPromiseState(), PromiseState::PENDING);
432     EXPECT_EQ(allPromise->GetPromiseResult(thread).IsUndefined(), true);
433 
434     /**
435      * @tc.steps: step5. p3.then((resolve)=>{print(resolve)}, (reject)=>{print(reject)});
436      */
437     JSHandle<JSFunction> nativeFuncRaceThenOnResolved =
438         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseAllThenOnResolved));
439     auto thenResult = ThanAlgorithm(thread, allPromise, nativeFuncRaceThenOnResolved.GetTaggedValue(),
440                                     nativeFuncRaceThenOnResolved.GetTaggedValue());
441     JSHandle<JSPromise> thenPromise(thread, thenResult);
442 
443     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
444     EXPECT_TRUE(thenPromise->GetPromiseResult(thread).IsUndefined());
445 
446     /**
447      * @tc.steps: step6. execute promise queue
448      */
449     auto microJobQueue = instance->GetMicroJobQueue();
450     if (!thread->HasPendingException()) {
451         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
452     }
453 }
454 
455 /*
456  * @tc.name: Catch
457  * @tc.desc: test Catch() method
458  * @tc.type: FUNC
459  */
HWTEST_F_L0(BuiltinsPromiseTest,Catch)460 HWTEST_F_L0(BuiltinsPromiseTest, Catch)
461 {
462     auto env = instance->GetGlobalEnv();
463     auto factory = instance->GetFactory();
464 
465     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
466     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(3));
467 
468     /**
469      * @tc.steps: step1. var p1 = Promise.reject(3)
470      */
471     auto result = PromiseAlgorithm(thread, promise, paramMsg1.GetTaggedValue(), AlgorithmType::REJECT);
472     JSHandle<JSPromise> rejectPromise(thread, result);
473     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
474     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), JSTaggedValue(3)), true);
475 
476     /**
477      * @tc.steps: step2. p1 invokes catch()
478      */
479     JSHandle<JSFunction> testPromiseCatch = factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseCatch));
480     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, rejectPromise.GetTaggedValue(), 6);
481     ecmaRuntimeCallInfo2->SetFunction(rejectPromise.GetTaggedValue());
482     ecmaRuntimeCallInfo2->SetThis(rejectPromise.GetTaggedValue());
483     ecmaRuntimeCallInfo2->SetCallArg(0, testPromiseCatch.GetTaggedValue());
484 
485     [[maybe_unused]] auto prevCatch = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
486     JSTaggedValue catchResult = BuiltinsPromise::Catch(ecmaRuntimeCallInfo2);
487     JSHandle<JSPromise> catchPromise(thread, catchResult);
488 
489     EXPECT_EQ(catchPromise->GetPromiseState(), PromiseState::PENDING);
490     EXPECT_EQ(catchPromise->GetPromiseResult(thread).IsUndefined(), true);
491     TestHelper::TearDownFrame(thread, prevCatch);
492 
493     /**
494      * @tc.steps: step3. execute promise queue
495      */
496     auto microJobQueue = instance->GetMicroJobQueue();
497     if (!thread->HasPendingException()) {
498         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
499     }
500 }
501 
502 /*
503  * @tc.name: ThenResolve
504  * @tc.desc: Testing the Then() function with the Resolve() function
505  * @tc.type: FUNC
506  */
HWTEST_F_L0(BuiltinsPromiseTest,ThenResolve)507 HWTEST_F_L0(BuiltinsPromiseTest, ThenResolve)
508 {
509     auto env = instance->GetGlobalEnv();
510     auto factory = instance->GetFactory();
511 
512     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
513     JSHandle<JSTaggedValue> paramMsg = JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("resolve"));
514 
515     /**
516      * @tc.steps: step1. var p1 = Promise.resolve("resolve")
517      */
518     auto result = PromiseAlgorithm(thread, promise, paramMsg.GetTaggedValue(), AlgorithmType::RESOLVE);
519     JSHandle<JSPromise> resolvePromise(thread, result);
520     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
521     EXPECT_EQ(JSTaggedValue::SameValue(thread, resolvePromise->GetPromiseResult(thread), paramMsg.GetTaggedValue()),
522               true);
523 
524     /**
525      * @tc.steps: step2. p1 invokes then()
526      */
527     JSHandle<JSFunction> testPromiseThenOnResolved =
528         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseThenOnResolved));
529     auto thenResult = ThanAlgorithm(thread, resolvePromise, testPromiseThenOnResolved.GetTaggedValue(),
530                                     JSTaggedValue::Undefined());
531     JSHandle<JSPromise> thenPromise(thread, thenResult);
532 
533     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
534     EXPECT_EQ(thenPromise->GetPromiseResult(thread).IsUndefined(), true);
535 
536     /**
537      * @tc.steps: step3.  execute promise queue
538      */
539     auto microJobQueue = instance->GetMicroJobQueue();
540     if (!thread->HasPendingException()) {
541         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
542     }
543 }
544 
545 /*
546  * @tc.name: ThenReject
547  * @tc.desc: Testing the Then() function with the Reject() function
548  * @tc.type: FUNC
549  */
HWTEST_F_L0(BuiltinsPromiseTest,ThenReject)550 HWTEST_F_L0(BuiltinsPromiseTest, ThenReject)
551 {
552     auto env = instance->GetGlobalEnv();
553     auto factory = instance->GetFactory();
554 
555     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
556     JSHandle<JSTaggedValue> paramMsg = JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("reject"));
557 
558     /**
559      * @tc.steps: step1. var p1 = Promise.Reject(5)
560      */
561     auto result = PromiseAlgorithm(thread, promise, paramMsg.GetTaggedValue(), AlgorithmType::REJECT);
562     JSHandle<JSPromise> rejectPromise(thread, result);
563     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
564     EXPECT_EQ(JSTaggedValue::SameValue(thread, rejectPromise->GetPromiseResult(thread), paramMsg.GetTaggedValue()),
565               true);
566 
567     /**
568      * @tc.steps: step1. p1 invokes then()
569      */
570     JSHandle<JSFunction> testPromiseThenOnRejected =
571         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseThenOnRejected));
572     auto thenResult = ThanAlgorithm(thread, rejectPromise, testPromiseThenOnRejected.GetTaggedValue(),
573                                     testPromiseThenOnRejected.GetTaggedValue());
574     JSHandle<JSPromise> thenPromise(thread, thenResult);
575     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
576     EXPECT_EQ(thenPromise->GetPromiseResult(thread).IsUndefined(), true);
577     /**
578      * @tc.steps: step3.  execute promise queue
579      */
580     auto microJobQueue = instance->GetMicroJobQueue();
581     if (!thread->HasPendingException()) {
582         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
583     }
584 }
585 }  // namespace panda::test
586