• 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 testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase()
41     {
42         GTEST_LOG_(INFO) << "SetUpTestCase";
43     }
44 
TearDownTestCase()45     static void TearDownTestCase()
46     {
47         GTEST_LOG_(INFO) << "TearDownCase";
48     }
49 
SetUp()50     void SetUp() override
51     {
52         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
53     }
54 
TearDown()55     void TearDown() override
56     {
57         TestHelper::DestroyEcmaVMWithScope(instance, scope);
58     }
59 
60     EcmaVM *instance {nullptr};
61     EcmaHandleScope *scope {nullptr};
62     JSThread *thread {nullptr};
63 };
64 
65 // native function for race2 then_on_rejected()
TestPromiseRaceThenOnRejectd(EcmaRuntimeCallInfo * argv)66 JSTaggedValue TestPromiseRaceThenOnRejectd(EcmaRuntimeCallInfo *argv)
67 {
68     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
69     // 12345 : test case
70     EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), JSTaggedValue(12345)), true);
71     return JSTaggedValue::Undefined();
72 }
73 
74 // native function for all then_on_resolved()
TestPromiseAllThenOnResolved(EcmaRuntimeCallInfo * argv)75 JSTaggedValue TestPromiseAllThenOnResolved(EcmaRuntimeCallInfo *argv)
76 {
77     JSHandle<JSTaggedValue> array = BuiltinsBase::GetCallArg(argv, 0);
78     JSHandle<JSObject> objectArray = JSHandle<JSObject>::Cast(array);
79     [[maybe_unused]] PropertyDescriptor desc(argv->GetThread());
80     [[maybe_unused]] bool result1 = JSObject::GetOwnProperty(
81         argv->GetThread(), objectArray, JSHandle<JSTaggedValue>(argv->GetThread(), JSTaggedValue(0)), desc);
82     EXPECT_TRUE(result1);
83     JSHandle<JSTaggedValue> value1 = desc.GetValue();
84     // 111 : test case
85     EXPECT_EQ(JSTaggedValue::SameValue(value1.GetTaggedValue(), JSTaggedValue(111)), true);
86     [[maybe_unused]] bool result2 = JSObject::GetOwnProperty(
87         argv->GetThread(), objectArray, JSHandle<JSTaggedValue>(argv->GetThread(), JSTaggedValue(1)), desc);
88     EXPECT_TRUE(result2);
89     JSHandle<JSTaggedValue> value2 = desc.GetValue();
90     // 222 : test case
91     EXPECT_EQ(JSTaggedValue::SameValue(value2.GetTaggedValue(), JSTaggedValue(222)), true);
92     return JSTaggedValue::Undefined();
93 }
94 
95 // native function for catch catch_on_rejected()
TestPromiseCatch(EcmaRuntimeCallInfo * argv)96 JSTaggedValue TestPromiseCatch(EcmaRuntimeCallInfo *argv)
97 {
98     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
99     // 3 : test case
100     EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), JSTaggedValue(3)), true);
101     return JSTaggedValue::Undefined();
102 }
103 
104 // native function for then then_on_resolved()
TestPromiseThenOnResolved(EcmaRuntimeCallInfo * argv)105 JSTaggedValue TestPromiseThenOnResolved(EcmaRuntimeCallInfo *argv)
106 {
107     auto factory = argv->GetThread()->GetEcmaVM()->GetFactory();
108     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
109     auto expect = factory->NewFromASCII("resolve");
110     EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), expect.GetTaggedValue()), true);
111     return JSTaggedValue::Undefined();
112 }
113 
114 // native function for then then_on_rejected()
TestPromiseThenOnRejected(EcmaRuntimeCallInfo * argv)115 JSTaggedValue TestPromiseThenOnRejected(EcmaRuntimeCallInfo *argv)
116 {
117     auto factory = argv->GetThread()->GetEcmaVM()->GetFactory();
118     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
119     auto expect = factory->NewFromASCII("reject");
120     EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), expect.GetTaggedValue()), true);
121     return JSTaggedValue::Undefined();
122 }
123 
124 /*
125  * @tc.name: Reject1
126  * @tc.desc: The reject method receives a number.
127  * @tc.type: FUNC
128  */
HWTEST_F_L0(BuiltinsPromiseTest,Reject1)129 HWTEST_F_L0(BuiltinsPromiseTest, Reject1)
130 {
131     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
132 
133     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
134     JSHandle<JSTaggedValue> paramMsg(thread, JSTaggedValue(3));
135 
136     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
137     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
138     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
139     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg.GetTaggedValue());
140 
141     /**
142      * @tc.steps: var p1 = Promise.reject(3).
143      */
144     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
145     JSTaggedValue result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
146     JSHandle<JSPromise> rejectPromise(thread, result);
147     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
148     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), JSTaggedValue(3)), true);
149     TestHelper::TearDownFrame(thread, prevReject);
150 }
151 
152 /*
153  * @tc.name: Reject2
154  * @tc.desc: The reject method receives a promise object.
155  * @tc.type: FUNC
156  */
HWTEST_F_L0(BuiltinsPromiseTest,Reject2)157 HWTEST_F_L0(BuiltinsPromiseTest, Reject2)
158 {
159     ObjectFactory *factory = instance->GetFactory();
160     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
161 
162     // constructor promise1
163     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
164     JSHandle<JSTaggedValue> paramMsg1 =
165         JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("Promise reject"));
166 
167     /**
168      * @tc.steps: step1. var p1 = Promise.reject("Promise reject")
169      */
170     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, promise.GetTaggedValue(), 6);
171     ecmaRuntimeCallInfo->SetFunction(promise.GetTaggedValue());
172     ecmaRuntimeCallInfo->SetThis(promise.GetTaggedValue());
173     ecmaRuntimeCallInfo->SetCallArg(0, paramMsg1.GetTaggedValue());
174 
175     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
176     JSTaggedValue result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo);
177     JSHandle<JSPromise> promise1(thread, result);
178     EXPECT_EQ(promise1->GetPromiseState(), PromiseState::REJECTED);
179     EXPECT_EQ(JSTaggedValue::SameValue(promise1->GetPromiseResult(), paramMsg1.GetTaggedValue()), true);
180     TestHelper::TearDownFrame(thread, prev);
181 
182     /**
183      * @tc.steps: step2. var p2 = Promise.reject(p1)
184      */
185     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, promise.GetTaggedValue(), 6);
186     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
187     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
188     ecmaRuntimeCallInfo1->SetCallArg(0, promise1.GetTaggedValue());
189     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
190 
191     JSTaggedValue result1 = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
192     JSHandle<JSPromise> promise2(thread, result1);
193     EXPECT_NE(*promise1, *promise2);
194     EXPECT_EQ(promise2->GetPromiseState(), PromiseState::REJECTED);
195     EXPECT_EQ(
196         JSTaggedValue::SameValue(promise2->GetPromiseResult(), JSTaggedValue(promise1.GetTaggedValue().GetRawData())),
197         true);
198     TestHelper::TearDownFrame(thread, prev);
199 }
200 
201 /*
202  * @tc.name: Resolve1
203  * @tc.desc: The resolve method receives a number.
204  * @tc.type: FUNC
205  */
HWTEST_F_L0(BuiltinsPromiseTest,Resolve1)206 HWTEST_F_L0(BuiltinsPromiseTest, Resolve1)
207 {
208     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
209 
210     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
211     JSHandle<JSTaggedValue> paramMsg(thread, JSTaggedValue(5));
212 
213     /**
214      * @tc.steps: step1. var p1 = Promise.resolve(12345)
215      */
216     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
217     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
218     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
219     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg.GetTaggedValue());
220 
221     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
222     JSTaggedValue result = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo1);
223     JSHandle<JSPromise> rejectPromise(thread, result);
224     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::FULFILLED);
225     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), JSTaggedValue(5)), true);
226     TestHelper::TearDownFrame(thread, prevReject);
227 }
228 
229 /*
230  * @tc.name: Resolve2
231  * @tc.desc: The resolve method receives a promise object.
232  * @tc.type: FUNC
233  */
HWTEST_F_L0(BuiltinsPromiseTest,Resolve2)234 HWTEST_F_L0(BuiltinsPromiseTest, Resolve2)
235 {
236     ObjectFactory *factory = instance->GetFactory();
237     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
238 
239     // constructor promise1
240     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
241     JSHandle<JSTaggedValue> paramMsg1 =
242         JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("Promise reject"));
243 
244     /**
245      * @tc.steps: step1. var p1 = Promise.reject("Promise reject")
246      */
247     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, promise.GetTaggedValue(), 6);
248     ecmaRuntimeCallInfo->SetFunction(promise.GetTaggedValue());
249     ecmaRuntimeCallInfo->SetThis(promise.GetTaggedValue());
250     ecmaRuntimeCallInfo->SetCallArg(0, paramMsg1.GetTaggedValue());
251 
252     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
253     JSTaggedValue result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo);
254     JSHandle<JSPromise> promise1(thread, result);
255     EXPECT_EQ(promise1->GetPromiseState(), PromiseState::REJECTED);
256     EXPECT_EQ(JSTaggedValue::SameValue(promise1->GetPromiseResult(), paramMsg1.GetTaggedValue()), true);
257     TestHelper::TearDownFrame(thread, prev);
258 
259     // promise1 Enter Reject() as a parameter.
260     /**
261      * @tc.steps: step2. var p2 = Promise.resolve(p1)
262      */
263     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, promise.GetTaggedValue(), 6);
264     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
265     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
266     ecmaRuntimeCallInfo1->SetCallArg(0, promise1.GetTaggedValue());
267     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
268 
269     JSTaggedValue result1 = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo1);
270     JSHandle<JSPromise> promise2(thread, result1);
271     EXPECT_EQ(*promise1, *promise2);
272     EXPECT_EQ(promise2->GetPromiseState(), PromiseState::REJECTED);
273     EXPECT_EQ(JSTaggedValue::SameValue(promise2->GetPromiseResult(), paramMsg1.GetTaggedValue()), true);
274     TestHelper::TearDownFrame(thread, prev1);
275 }
276 
277 /*
278  * @tc.name: Race1
279  * @tc.desc: The race method receives an array.
280  * @tc.type: FUNC
281  */
HWTEST_F_L0(BuiltinsPromiseTest,Race1)282 HWTEST_F_L0(BuiltinsPromiseTest, Race1)
283 {
284     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
285 
286     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
287     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(12345));
288     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(6789));
289 
290     /**
291      * @tc.steps: step1. var p1 = Promise.reject(12345)
292      */
293     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
294     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
295     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
296     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg1.GetTaggedValue());
297 
298     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
299     JSTaggedValue result1 = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
300     JSHandle<JSPromise> rejectPromise(thread, result1);
301     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
302     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), JSTaggedValue(12345)), true);
303     TestHelper::TearDownFrame(thread, prevReject);
304 
305     /**
306      * @tc.steps: step2. var p2 = Promise.resolve(6789)
307      */
308     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
309     ecmaRuntimeCallInfo2->SetFunction(promise.GetTaggedValue());
310     ecmaRuntimeCallInfo2->SetThis(promise.GetTaggedValue());
311     ecmaRuntimeCallInfo2->SetCallArg(0, paramMsg2.GetTaggedValue());
312 
313     [[maybe_unused]] auto prevResolve = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
314     JSTaggedValue result2 = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo2);
315     JSHandle<JSPromise> resolvePromise(thread, result2);
316     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
317     EXPECT_EQ(JSTaggedValue::SameValue(resolvePromise->GetPromiseResult(), JSTaggedValue(6789)), true);
318     TestHelper::TearDownFrame(thread, prevResolve);
319 
320     /**
321      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
322      */
323     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
324     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(rejectPromise));
325     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
326 
327     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise));
328     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
329 
330     /**
331      * @tc.steps: step4. var p3 = Promise.race([p1,p2]);
332      */
333     auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
334     ecmaRuntimeCallInfo4->SetFunction(promise.GetTaggedValue());
335     ecmaRuntimeCallInfo4->SetThis(promise.GetTaggedValue());
336     ecmaRuntimeCallInfo4->SetCallArg(0, array.GetTaggedValue());
337 
338     [[maybe_unused]] auto prev4 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
339     JSTaggedValue result4 = BuiltinsPromise::Race(ecmaRuntimeCallInfo4);
340     JSHandle<JSPromise> racePromise(thread, result4);
341     EXPECT_EQ(racePromise->GetPromiseState(), PromiseState::PENDING);
342     EXPECT_EQ(racePromise->GetPromiseResult().IsUndefined(), true);
343     TestHelper::TearDownFrame(thread, prev4);
344 }
345 
346 /*
347  * @tc.name: Race2
348  * @tc.desc: The Race method receives an array, uses the Then method to save the task in the task queue, and outputs
349  * the execution result of the queue.
350  * @tc.type: FUNC
351  */
HWTEST_F_L0(BuiltinsPromiseTest,Race2)352 HWTEST_F_L0(BuiltinsPromiseTest, Race2)
353 {
354     ObjectFactory *factory = instance->GetFactory();
355     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
356 
357     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
358     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(12345));
359     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(6789));
360 
361     /**
362      * @tc.steps: step1. var p1 = Promise.reject(12345)
363      */
364     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
365     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
366     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
367     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg1.GetTaggedValue());
368 
369     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
370     JSTaggedValue result1 = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
371     JSHandle<JSPromise> rejectPromise(thread, result1);
372     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
373     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), JSTaggedValue(12345)), true);
374     TestHelper::TearDownFrame(thread, prevReject);
375 
376     /**
377      * @tc.steps: step2. var p2 = Promise.resolve(6789)
378      */
379     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
380     ecmaRuntimeCallInfo2->SetFunction(promise.GetTaggedValue());
381     ecmaRuntimeCallInfo2->SetThis(promise.GetTaggedValue());
382     ecmaRuntimeCallInfo2->SetCallArg(0, paramMsg2.GetTaggedValue());
383 
384     [[maybe_unused]] auto prevResolve = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
385     JSTaggedValue result2 = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo2);
386     JSHandle<JSPromise> resolvePromise(thread, result2);
387     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
388     EXPECT_EQ(JSTaggedValue::SameValue(resolvePromise->GetPromiseResult(), JSTaggedValue(6789)), true);
389     TestHelper::TearDownFrame(thread, prevResolve);
390 
391     /**
392      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
393      */
394     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
395     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(rejectPromise));
396     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
397 
398     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise));
399     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
400 
401     /**
402      * @tc.steps: step4. var p3 = Promise.race([p1,p2]);
403      */
404     auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
405     ecmaRuntimeCallInfo4->SetFunction(promise.GetTaggedValue());
406     ecmaRuntimeCallInfo4->SetThis(promise.GetTaggedValue());
407     ecmaRuntimeCallInfo4->SetCallArg(0, array.GetTaggedValue());
408 
409     [[maybe_unused]] auto prev4 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
410     JSTaggedValue result4 = BuiltinsPromise::Race(ecmaRuntimeCallInfo4);
411     JSHandle<JSPromise> racePromise(thread, result4);
412     EXPECT_EQ(racePromise->GetPromiseState(), PromiseState::PENDING);
413     EXPECT_EQ(racePromise->GetPromiseResult().IsUndefined(), true);
414     TestHelper::TearDownFrame(thread, prev4);
415 
416     /**
417      * @tc.steps: step5. p3.then((resolve)=>{print(resolve)}, (reject)=>{print(reject)})
418      */
419     JSHandle<JSFunction> native_func_race_then_onrejected =
420         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseRaceThenOnRejectd));
421     auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, racePromise.GetTaggedValue(), 8);
422     ecmaRuntimeCallInfo5->SetFunction(racePromise.GetTaggedValue());
423     ecmaRuntimeCallInfo5->SetThis(racePromise.GetTaggedValue());
424     ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue::Undefined());
425     ecmaRuntimeCallInfo5->SetCallArg(1, native_func_race_then_onrejected.GetTaggedValue());
426 
427     [[maybe_unused]] auto prev5 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
428     JSTaggedValue thenResult = BuiltinsPromise::Then(ecmaRuntimeCallInfo5);
429     JSHandle<JSPromise> thenPromise(thread, thenResult);
430 
431     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
432     EXPECT_TRUE(thenPromise->GetPromiseResult().IsUndefined());
433     TestHelper::TearDownFrame(thread, prev5);
434 
435     /**
436      * @tc.steps: step6. execute promise queue
437      */
438     auto microJobQueue = instance->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue();
439     if (!thread->HasPendingException()) {
440         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
441     }
442 }
443 
444 /*
445  * @tc.name: All
446  * @tc.desc: The All method receives an array, uses the Then method to save the task in the task queue, and outputs the
447  * execution result of the queue.
448  * @tc.type: FUNC
449  */
HWTEST_F_L0(BuiltinsPromiseTest,All)450 HWTEST_F_L0(BuiltinsPromiseTest, All)
451 {
452     ObjectFactory *factory = instance->GetFactory();
453     JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
454 
455     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
456     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(111));
457     JSHandle<JSTaggedValue> paramMsg2(thread, JSTaggedValue(222));
458 
459     /**
460      * @tc.steps: step1. var p1 = Promise.resolve(111)
461      */
462     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
463     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
464     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
465     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg1.GetTaggedValue());
466 
467     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
468     JSTaggedValue result1 = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo1);
469     JSHandle<JSPromise> resolvePromise1(thread, result1);
470     EXPECT_EQ(resolvePromise1->GetPromiseState(), PromiseState::FULFILLED);
471     EXPECT_EQ(JSTaggedValue::SameValue(resolvePromise1->GetPromiseResult(), JSTaggedValue(111)), true);
472     TestHelper::TearDownFrame(thread, prevReject);
473 
474     /**
475      * @tc.steps: step2. var p2 = Promise.resolve(222)
476      */
477     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
478     ecmaRuntimeCallInfo2->SetFunction(promise.GetTaggedValue());
479     ecmaRuntimeCallInfo2->SetThis(promise.GetTaggedValue());
480     ecmaRuntimeCallInfo2->SetCallArg(0, paramMsg2.GetTaggedValue());
481 
482     [[maybe_unused]] auto prevResolve = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
483     JSTaggedValue result2 = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo2);
484     JSHandle<JSPromise> resolvePromise2(thread, result2);
485     EXPECT_EQ(resolvePromise2->GetPromiseState(), PromiseState::FULFILLED);
486     EXPECT_EQ(JSTaggedValue::SameValue(resolvePromise2->GetPromiseResult(), JSTaggedValue(222)), true);
487     TestHelper::TearDownFrame(thread, prevResolve);
488 
489     /**
490      * @tc.steps: step3. Construct an array with two elements p1 and p2. array = [p1. p2]
491      */
492     JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
493     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise1));
494     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
495 
496     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>::Cast(resolvePromise2));
497     JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
498 
499     /**
500      * @tc.steps: step4. var p3 = Promise.all([p1,p2]);
501      */
502     auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
503     ecmaRuntimeCallInfo4->SetFunction(promise.GetTaggedValue());
504     ecmaRuntimeCallInfo4->SetThis(promise.GetTaggedValue());
505     ecmaRuntimeCallInfo4->SetCallArg(0, array.GetTaggedValue());
506 
507     [[maybe_unused]] auto prev4 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
508     JSTaggedValue result4 = BuiltinsPromise::All(ecmaRuntimeCallInfo4);
509     JSHandle<JSPromise> allPromise(thread, result4);
510     EXPECT_EQ(allPromise->GetPromiseState(), PromiseState::PENDING);
511     EXPECT_EQ(allPromise->GetPromiseResult().IsUndefined(), true);
512     TestHelper::TearDownFrame(thread, prev4);
513 
514     /**
515      * @tc.steps: step5. p3.then((resolve)=>{print(resolve)}, (reject)=>{print(reject)});
516      */
517     JSHandle<JSFunction> nativeFuncRaceThenOnResolved =
518         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseAllThenOnResolved));
519     auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, allPromise.GetTaggedValue(), 8);
520     ecmaRuntimeCallInfo5->SetFunction(allPromise.GetTaggedValue());
521     ecmaRuntimeCallInfo5->SetThis(allPromise.GetTaggedValue());
522     ecmaRuntimeCallInfo5->SetCallArg(0, nativeFuncRaceThenOnResolved.GetTaggedValue());
523     ecmaRuntimeCallInfo5->SetCallArg(1, nativeFuncRaceThenOnResolved.GetTaggedValue());
524 
525     [[maybe_unused]] auto prev5 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
526     JSTaggedValue thenResult = BuiltinsPromise::Then(ecmaRuntimeCallInfo5);
527     JSHandle<JSPromise> thenPromise(thread, thenResult);
528 
529     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
530     EXPECT_TRUE(thenPromise->GetPromiseResult().IsUndefined());
531     TestHelper::TearDownFrame(thread, prev5);
532 
533     /**
534      * @tc.steps: step6. execute promise queue
535      */
536     auto microJobQueue = instance->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue();
537     if (!thread->HasPendingException()) {
538         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
539     }
540 }
541 
542 /*
543  * @tc.name: Catch
544  * @tc.desc: test Catch() method
545  * @tc.type: FUNC
546  */
HWTEST_F_L0(BuiltinsPromiseTest,Catch)547 HWTEST_F_L0(BuiltinsPromiseTest, Catch)
548 {
549     auto env = instance->GetGlobalEnv();
550     auto factory = instance->GetFactory();
551 
552     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
553     JSHandle<JSTaggedValue> paramMsg1(thread, JSTaggedValue(3));
554 
555     /**
556      * @tc.steps: step1. var p1 = Promise.reject(3)
557      */
558     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
559     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
560     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
561     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg1.GetTaggedValue());
562 
563     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
564     JSTaggedValue result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
565     JSHandle<JSPromise> rejectPromise(thread, result);
566     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
567     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), JSTaggedValue(3)), true);
568     TestHelper::TearDownFrame(thread, prevReject);
569 
570     /**
571      * @tc.steps: step2. p1 invokes catch()
572      */
573     JSHandle<JSFunction> testPromiseCatch = factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseCatch));
574     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, rejectPromise.GetTaggedValue(), 6);
575     ecmaRuntimeCallInfo2->SetFunction(rejectPromise.GetTaggedValue());
576     ecmaRuntimeCallInfo2->SetThis(rejectPromise.GetTaggedValue());
577     ecmaRuntimeCallInfo2->SetCallArg(0, testPromiseCatch.GetTaggedValue());
578 
579     [[maybe_unused]] auto prevCatch = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
580     JSTaggedValue catchResult = BuiltinsPromise::Catch(ecmaRuntimeCallInfo2);
581     JSHandle<JSPromise> catchPromise(thread, catchResult);
582 
583     EXPECT_EQ(catchPromise->GetPromiseState(), PromiseState::PENDING);
584     EXPECT_EQ(catchPromise->GetPromiseResult().IsUndefined(), true);
585     TestHelper::TearDownFrame(thread, prevCatch);
586 
587     /**
588      * @tc.steps: step3. execute promise queue
589      */
590     auto microJobQueue = instance->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue();
591     if (!thread->HasPendingException()) {
592         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
593     }
594 }
595 
596 /*
597  * @tc.name: ThenResolve
598  * @tc.desc: Testing the Then() function with the Resolve() function
599  * @tc.type: FUNC
600  */
HWTEST_F_L0(BuiltinsPromiseTest,ThenResolve)601 HWTEST_F_L0(BuiltinsPromiseTest, ThenResolve)
602 {
603     auto env = instance->GetGlobalEnv();
604     auto factory = instance->GetFactory();
605 
606     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
607     JSHandle<JSTaggedValue> paramMsg = JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("resolve"));
608 
609     /**
610      * @tc.steps: step1. var p1 = Promise.resolve("resolve")
611      */
612     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
613     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
614     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
615     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg.GetTaggedValue());
616 
617     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
618     JSTaggedValue result = BuiltinsPromise::Resolve(ecmaRuntimeCallInfo1);
619     JSHandle<JSPromise> resolvePromise(thread, result);
620     EXPECT_EQ(resolvePromise->GetPromiseState(), PromiseState::FULFILLED);
621     EXPECT_EQ(JSTaggedValue::SameValue(resolvePromise->GetPromiseResult(), paramMsg.GetTaggedValue()), true);
622     TestHelper::TearDownFrame(thread, prevReject);
623 
624     /**
625      * @tc.steps: step2. p1 invokes then()
626      */
627     JSHandle<JSFunction> testPromiseThenOnResolved =
628         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseThenOnResolved));
629     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, resolvePromise.GetTaggedValue(), 8);
630     ecmaRuntimeCallInfo2->SetFunction(resolvePromise.GetTaggedValue());
631     ecmaRuntimeCallInfo2->SetThis(resolvePromise.GetTaggedValue());
632     ecmaRuntimeCallInfo2->SetCallArg(0, testPromiseThenOnResolved.GetTaggedValue());
633     ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue::Undefined());
634 
635     [[maybe_unused]] auto prevThen = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
636     JSTaggedValue thenResult = BuiltinsPromise::Then(ecmaRuntimeCallInfo2);
637     JSHandle<JSPromise> thenPromise(thread, thenResult);
638 
639     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
640     EXPECT_EQ(thenPromise->GetPromiseResult().IsUndefined(), true);
641     TestHelper::TearDownFrame(thread, prevThen);
642 
643     /**
644      * @tc.steps: step3.  execute promise queue
645      */
646     auto microJobQueue = instance->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue();
647     if (!thread->HasPendingException()) {
648         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
649     }
650 }
651 
652 /*
653  * @tc.name: ThenReject
654  * @tc.desc: Testing the Then() function with the Reject() function
655  * @tc.type: FUNC
656  */
HWTEST_F_L0(BuiltinsPromiseTest,ThenReject)657 HWTEST_F_L0(BuiltinsPromiseTest, ThenReject)
658 {
659     auto env = instance->GetGlobalEnv();
660     auto factory = instance->GetFactory();
661 
662     JSHandle<JSFunction> promise = JSHandle<JSFunction>::Cast(env->GetPromiseFunction());
663     JSHandle<JSTaggedValue> paramMsg = JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("reject"));
664 
665     /**
666      * @tc.steps: step1. var p1 = Promise.Reject(5)
667      */
668     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*promise), 6);
669     ecmaRuntimeCallInfo1->SetFunction(promise.GetTaggedValue());
670     ecmaRuntimeCallInfo1->SetThis(promise.GetTaggedValue());
671     ecmaRuntimeCallInfo1->SetCallArg(0, paramMsg.GetTaggedValue());
672 
673     [[maybe_unused]] auto prevReject = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
674     JSTaggedValue result = BuiltinsPromise::Reject(ecmaRuntimeCallInfo1);
675     JSHandle<JSPromise> rejectPromise(thread, result);
676     EXPECT_EQ(rejectPromise->GetPromiseState(), PromiseState::REJECTED);
677     EXPECT_EQ(JSTaggedValue::SameValue(rejectPromise->GetPromiseResult(), paramMsg.GetTaggedValue()), true);
678     TestHelper::TearDownFrame(thread, prevReject);
679 
680     /**
681      * @tc.steps: step1. p1 invokes then()
682      */
683     JSHandle<JSFunction> testPromiseThenOnRejected =
684         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseThenOnRejected));
685     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, rejectPromise.GetTaggedValue(), 8);
686     ecmaRuntimeCallInfo2->SetFunction(rejectPromise.GetTaggedValue());
687     ecmaRuntimeCallInfo2->SetThis(rejectPromise.GetTaggedValue());
688     ecmaRuntimeCallInfo2->SetCallArg(0, testPromiseThenOnRejected.GetTaggedValue());
689     ecmaRuntimeCallInfo2->SetCallArg(1, testPromiseThenOnRejected.GetTaggedValue());
690 
691     [[maybe_unused]] auto prevThen = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
692     JSTaggedValue thenResult = BuiltinsPromise::Then(ecmaRuntimeCallInfo2);
693     JSHandle<JSPromise> thenPromise(thread, thenResult);
694 
695     EXPECT_EQ(thenPromise->GetPromiseState(), PromiseState::PENDING);
696     EXPECT_EQ(thenPromise->GetPromiseResult().IsUndefined(), true);
697     TestHelper::TearDownFrame(thread, prevThen);
698     /**
699      * @tc.steps: step3.  execute promise queue
700      */
701     auto microJobQueue = instance->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue();
702     if (!thread->HasPendingException()) {
703         job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
704     }
705 }
706 }  // namespace panda::test
707