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