• 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/jobs/pending_job.h"
17 
18 #include "ecmascript/base/builtins_base.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_promise.h"
21 #include "ecmascript/tagged_array.h"
22 #include "ecmascript/tests/test_helper.h"
23 
24 using namespace panda::ecmascript;
25 using namespace panda::ecmascript::base;
26 
27 namespace panda::test {
28 using PendingJob = ecmascript::job::PendingJob;
29 class PendingJobTest : public testing::Test {
30 public:
SetUpTestCase()31     static void SetUpTestCase()
32     {
33         GTEST_LOG_(INFO) << "SetUpTestCase";
34     }
35 
TearDownTestCase()36     static void TearDownTestCase()
37     {
38         GTEST_LOG_(INFO) << "TearDownCase";
39     }
40 
SetUp()41     void SetUp() override
42     {
43         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
44     }
45 
TearDown()46     void TearDown() override
47     {
48         TestHelper::DestroyEcmaVMWithScope(instance, scope);
49     }
50 
51     EcmaVM *instance {nullptr};
52     EcmaHandleScope *scope {nullptr};
53     JSThread *thread {nullptr};
54 };
55 
56 /**
57  * @tc.name: GetJob
58  * @tc.desc: Check whether the result returned through "GetJob" function is within expectations.
59  * @tc.type: FUNC
60  * @tc.require:
61  */
HWTEST_F_L0(PendingJobTest,GetJob)62 HWTEST_F_L0(PendingJobTest, GetJob)
63 {
64     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
65     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
66 
67     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(0);
68     JSHandle<JSFunction> handleFunc = factory->NewJSFunction(env);
69 
70     JSHandle<JSTaggedValue> handlePendingJobVal(factory->NewPendingJob(handleFunc, handleArgv));
71     EXPECT_TRUE(handlePendingJobVal->IsPendingJob());
72     JSHandle<PendingJob> handlePendingJob(handlePendingJobVal);
73     EXPECT_TRUE(handlePendingJob->GetJob().IsJSFunction());
74 
75     JSHandle<JSFunction> handleNativeFunc(env->GetTypedArrayFunction());
76     handlePendingJob->SetJob(thread, handleNativeFunc.GetTaggedValue());
77     EXPECT_EQ(JSTaggedValue::SameValue(handlePendingJob->GetJob(), handleNativeFunc.GetTaggedValue()), true);
78 }
79 
80 /**
81  * @tc.name: GetArguments
82  * @tc.desc: Check whether the result returned through "GetArguments" function is within expectations.
83  * @tc.type: FUNC
84  * @tc.require:
85  */
HWTEST_F_L0(PendingJobTest,GetArguments)86 HWTEST_F_L0(PendingJobTest, GetArguments)
87 {
88     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
89     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
90 
91     JSHandle<TaggedArray> handleArgv1 = factory->NewTaggedArray(0);
92     JSHandle<JSFunction> handleFunc = factory->NewJSFunction(env);
93 
94     JSHandle<JSTaggedValue> handlePendingJobVal(factory->NewPendingJob(handleFunc, handleArgv1));
95     EXPECT_TRUE(handlePendingJobVal->IsPendingJob());
96     JSHandle<PendingJob> handlePendingJob(handlePendingJobVal);
97     EXPECT_TRUE(handlePendingJob->GetArguments().IsTaggedArray());
98 
99     JSHandle<TaggedArray> handleArgv2 = factory->NewTaggedArray(1);
100     handleArgv2->Set(thread, 0, JSTaggedValue(1));
101     handlePendingJob->SetArguments(thread, handleArgv2.GetTaggedValue());
102 
103     JSHandle<TaggedArray> resultArray(thread, handlePendingJob->GetArguments());
104     EXPECT_EQ(resultArray->GetLength(), 1U);
105     EXPECT_EQ(resultArray->Get(0).GetInt(), 1);
106 }
107 
108 /**
109  * @tc.name: ExecutePendingJob_001
110  * @tc.desc: Get a function called PromiseReactionJob from env.According to the definition of function,define a
111  *           TaggedArray object with length of two.set the required value and define a pendingjob object according
112  *           to both.the pendingjob object call "ExecutePendingJob" function to execute the method of function and
113  *           return the value of the method.
114  * @tc.type: FUNC
115  * @tc.require:
116  */
HWTEST_F_L0(PendingJobTest,ExecutePendingJob_001)117 HWTEST_F_L0(PendingJobTest, ExecutePendingJob_001)
118 {
119     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
120     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
121     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
122 
123     JSHandle<PromiseCapability> capbility = JSPromise::NewPromiseCapability(thread, promiseFunc);
124     JSHandle<JSTaggedValue> reject(thread, capbility->GetReject());
125 
126     JSHandle<PromiseReaction> rejectReaction = factory->NewPromiseReaction();
127     rejectReaction->SetPromiseCapability(thread, capbility.GetTaggedValue());
128     rejectReaction->SetHandler(thread, reject.GetTaggedValue());
129 
130     JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
131     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(2);
132     handleArgv->Set(thread, 0, rejectReaction.GetTaggedValue());
133     handleArgv->Set(thread, 1, JSTaggedValue(44));
134 
135     JSHandle<PendingJob> handlePendingJob = factory->NewPendingJob(promiseReactionsJob, handleArgv);
136     JSTaggedValue callResult = PendingJob::ExecutePendingJob(handlePendingJob, thread);
137     EXPECT_EQ(callResult, JSTaggedValue::Undefined());
138     JSHandle<JSPromise> jsPromise(thread, capbility->GetPromise());
139     EXPECT_EQ(jsPromise->GetPromiseState(), PromiseState::REJECTED);
140     EXPECT_EQ(JSTaggedValue::SameValue(jsPromise->GetPromiseResult(), JSTaggedValue(44)), true);
141 }
142 
143 /**
144  * @tc.name: ExecutePendingJob_002
145  * @tc.desc: Get a function called PromiseReactionJob from env.According to the definition of function,define a
146  *           TaggedArray object with length of two.set the required value and define a pendingjob object according
147  *           to both.the pendingjob object call "ExecutePendingJob" function to execute the method of function and
148  *           return the value of the method.
149  * @tc.type: FUNC
150  * @tc.require:
151  */
HWTEST_F_L0(PendingJobTest,ExecutePendingJob_002)152 HWTEST_F_L0(PendingJobTest, ExecutePendingJob_002)
153 {
154     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
155     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
156     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
157     JSHandle<JSTaggedValue> paramMsg(factory->NewFromASCII("resolve"));
158 
159     JSHandle<PromiseCapability> capbility = JSPromise::NewPromiseCapability(thread, promiseFunc);
160     JSHandle<JSTaggedValue> resolve(thread, capbility->GetResolve());
161 
162     JSHandle<PromiseReaction> fulfillReaction = factory->NewPromiseReaction();
163     fulfillReaction->SetPromiseCapability(thread, capbility.GetTaggedValue());
164     fulfillReaction->SetHandler(thread, resolve.GetTaggedValue());
165 
166     JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
167     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(2);
168     handleArgv->Set(thread, 0, fulfillReaction.GetTaggedValue());
169     handleArgv->Set(thread, 1, paramMsg.GetTaggedValue());
170 
171     JSHandle<PendingJob> handlePendingJob = factory->NewPendingJob(promiseReactionsJob, handleArgv);
172     JSTaggedValue callResult = PendingJob::ExecutePendingJob(handlePendingJob, thread);
173     EXPECT_EQ(callResult, JSTaggedValue::Undefined());
174     JSHandle<JSPromise> jsPromise(thread, capbility->GetPromise());
175     EXPECT_EQ(jsPromise->GetPromiseState(), PromiseState::FULFILLED);
176     EXPECT_EQ(JSTaggedValue::SameValue(jsPromise->GetPromiseResult(), paramMsg.GetTaggedValue()), true);
177 }
178 
179 /**
180  * @tc.name: ExecutePendingJob_003
181  * @tc.desc: Get a function called PromiseReactionJob from env.According to the definition of function,define a
182  *           TaggedArray object with length of two.set the required value and define a pendingjob object according
183  *           to both.the pendingjob object call "ExecutePendingJob" function to execute the method of function and
184  *           return the value of the method.
185  * @tc.type: FUNC
186  * @tc.require:
187  */
HWTEST_F_L0(PendingJobTest,ExecutePendingJob_003)188 HWTEST_F_L0(PendingJobTest, ExecutePendingJob_003)
189 {
190     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
191     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
192     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
193     JSHandle<JSTaggedValue> paramMsg(factory->NewFromASCII("Thrower"));
194 
195     JSHandle<PromiseCapability> capbility = JSPromise::NewPromiseCapability(thread, promiseFunc);
196     JSHandle<PromiseReaction> rejectReaction = factory->NewPromiseReaction();
197     rejectReaction->SetPromiseCapability(thread, capbility.GetTaggedValue());
198     rejectReaction->SetHandler(thread, paramMsg.GetTaggedValue());
199 
200     JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
201     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(2);
202     handleArgv->Set(thread, 0, rejectReaction.GetTaggedValue());
203     handleArgv->Set(thread, 1, JSTaggedValue::Undefined());
204 
205     JSHandle<PendingJob> handlePendingJob = factory->NewPendingJob(promiseReactionsJob, handleArgv);
206     JSTaggedValue callResult = PendingJob::ExecutePendingJob(handlePendingJob, thread);
207     EXPECT_EQ(callResult, JSTaggedValue::Undefined());
208     JSHandle<JSPromise> jsPromise(thread, capbility->GetPromise());
209     EXPECT_EQ(jsPromise->GetPromiseState(), PromiseState::REJECTED);
210     EXPECT_EQ(JSTaggedValue::SameValue(jsPromise->GetPromiseResult(), JSTaggedValue::Undefined()), true);
211 }
212 
TestPromiseOnResolved(EcmaRuntimeCallInfo * argv)213 JSTaggedValue TestPromiseOnResolved(EcmaRuntimeCallInfo *argv)
214 {
215     auto factory = argv->GetThread()->GetEcmaVM()->GetFactory();
216     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
217     EXPECT_TRUE(result->IsPromiseReaction());
218     auto handlerMsg = factory->NewFromASCII("after_resolve");
219     JSHandle<PromiseReaction> reaction = JSHandle<PromiseReaction>::Cast(result);
220     JSHandle<JSTaggedValue> handler(argv->GetThread(), reaction->GetHandler());
221     EXPECT_EQ(JSTaggedValue::SameValue(handler.GetTaggedValue(), handlerMsg.GetTaggedValue()), true);
222     return JSTaggedValue::Undefined();
223 }
224 
225 /**
226  * @tc.name: ExecutePendingJob_004
227  * @tc.desc: Create a function called TestPromiseOnResolved.According to the definition of function,define a TaggedArray
228  *           object with length of two.set the required value and define a pendingjob object according to both.
229  *           the pendingjob object call "ExecutePendingJob" function to execute the method of function and return the
230  *           value of the method.
231  * @tc.type: FUNC
232  * @tc.require:
233  */
HWTEST_F_L0(PendingJobTest,ExecutePendingJob_004)234 HWTEST_F_L0(PendingJobTest, ExecutePendingJob_004)
235 {
236     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
237     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
238     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
239     JSHandle<JSTaggedValue> paramMsg(factory->NewFromASCII("after_resolve"));
240 
241     JSHandle<PromiseCapability> capbility = JSPromise::NewPromiseCapability(thread, promiseFunc);
242     JSHandle<JSTaggedValue> resolve(thread, capbility->GetResolve());
243 
244     JSHandle<PromiseReaction> fulfillReaction = factory->NewPromiseReaction();
245     fulfillReaction->SetPromiseCapability(thread, capbility.GetTaggedValue());
246     fulfillReaction->SetHandler(thread, paramMsg.GetTaggedValue());
247 
248     JSHandle<JSFunction> testPromiseResolved =
249         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseOnResolved));
250     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(2);
251     handleArgv->Set(thread, 0, fulfillReaction.GetTaggedValue());
252     handleArgv->Set(thread, 1, JSTaggedValue::Undefined());
253 
254     JSHandle<PendingJob> handlePendingJob = factory->NewPendingJob(testPromiseResolved, handleArgv);
255     JSTaggedValue callResult = PendingJob::ExecutePendingJob(handlePendingJob, thread);
256     EXPECT_EQ(callResult, JSTaggedValue::Undefined());
257     JSHandle<JSPromise> jsPromise(thread, capbility->GetPromise());
258     EXPECT_EQ(jsPromise->GetPromiseState(), PromiseState::PENDING);
259     EXPECT_EQ(jsPromise->GetPromiseResult().IsUndefined(), true);
260 }
261 
TestPromiseResolveThenableJob(EcmaRuntimeCallInfo * argv)262 JSTaggedValue TestPromiseResolveThenableJob(EcmaRuntimeCallInfo *argv)
263 {
264     JSHandle<JSTaggedValue> result = BuiltinsBase::GetCallArg(argv, 0);
265     EXPECT_TRUE(result->IsJSFunction());
266     JSHandle<JSTaggedValue> undefined(argv->GetThread(), JSTaggedValue::Undefined());
267     EcmaRuntimeCallInfo *info =
268         EcmaInterpreter::NewRuntimeCallInfo(argv->GetThread(), result, undefined, undefined, 1);
269     info->SetCallArg(JSTaggedValue(44));  // 44 : 44 promise result
270     return JSFunction::Call(info);
271 }
272 
273 /**
274  * @tc.name: ExecutePendingJob_005
275  * @tc.desc: Get a function called promiseresolvethenablejob from env. According to the definition of function,
276  *           define a TaggedArray object with length of three.set the required value and define a pendingjob object
277  *           according to both.The pendingjob object call "ExecutePendingJob" function to execute the method of function
278  *           and return the value of the method.
279  * @tc.type: FUNC
280  * @tc.require:
281  */
HWTEST_F_L0(PendingJobTest,ExecutePendingJob_005)282 HWTEST_F_L0(PendingJobTest, ExecutePendingJob_005)
283 {
284     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
285     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
286     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
287     JSHandle<JSTaggedValue> paramMsg(thread, JSTaggedValue::Undefined());
288 
289     JSHandle<JSPromise> jsPromise =
290         JSHandle<JSPromise>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(promiseFunc), promiseFunc));
291     JSHandle<JSFunction> testPromiseResolveThenableJob =
292         factory->NewJSFunction(env, reinterpret_cast<void *>(TestPromiseResolveThenableJob));
293 
294     JSHandle<JSFunction> promiseResolveThenableJob(env->GetPromiseResolveThenableJob());
295     JSHandle<TaggedArray> handleArgv = factory->NewTaggedArray(3);
296     handleArgv->Set(thread, 0, jsPromise.GetTaggedValue());
297     handleArgv->Set(thread, 1, paramMsg.GetTaggedValue());
298     handleArgv->Set(thread, 2, testPromiseResolveThenableJob.GetTaggedValue());
299 
300     JSHandle<PendingJob> handlePendingJob = factory->NewPendingJob(promiseResolveThenableJob, handleArgv);
301     JSTaggedValue callResult = PendingJob::ExecutePendingJob(handlePendingJob, thread);
302     EXPECT_EQ(callResult, JSTaggedValue::Undefined());
303 
304     EXPECT_EQ(jsPromise->GetPromiseState(), PromiseState::FULFILLED);
305     EXPECT_EQ(JSTaggedValue::SameValue(jsPromise->GetPromiseResult(), JSTaggedValue(44)), true);
306 }
307 } // namespace panda::test
308