1/* 2 * Copyright (c) 2023-2024 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 <cstddef> 17#include "ecmascript/builtins/builtins.h" 18#include "ecmascript/builtins/builtins_function.h" 19#include "ecmascript/builtins/builtins_object.h" 20#include "ecmascript/compiler/aot_file/an_file_data_manager.h" 21#include "ecmascript/compiler/aot_file/aot_file_manager.h" 22#include "ecmascript/compiler/circuit_builder_helper.h" 23#include "ecmascript/deoptimizer/deoptimizer.h" 24#include "ecmascript/ecma_global_storage.h" 25#include "ecmascript/ecma_vm.h" 26#include "ecmascript/global_env.h" 27#include "ecmascript/js_api/js_api_tree_map.h" 28#include "ecmascript/js_api/js_api_tree_set.h" 29#include "ecmascript/js_api/js_api_vector.h" 30#include "ecmascript/js_array.h" 31#include "ecmascript/js_bigint.h" 32#include "ecmascript/js_date_time_format.h" 33#include "ecmascript/js_generator_object.h" 34#include "ecmascript/js_map.h" 35#include "ecmascript/js_map_iterator.h" 36#include "ecmascript/js_object-inl.h" 37#include "ecmascript/js_primitive_ref.h" 38#include "ecmascript/js_regexp.h" 39#include "ecmascript/js_runtime_options.h" 40#include "ecmascript/js_set.h" 41#include "ecmascript/js_set_iterator.h" 42#include "ecmascript/js_tagged_value.h" 43#include "ecmascript/js_thread.h" 44#include "ecmascript/js_weak_container.h" 45#include "ecmascript/linked_hash_table.h" 46#include "ecmascript/mem/mem_map_allocator.h" 47#include "ecmascript/module/js_module_manager.h" 48#include "ecmascript/module/js_module_source_text.h" 49#include "ecmascript/napi/include/jsnapi.h" 50#include "ecmascript/napi/include/jsnapi_internals.h" 51#include "ecmascript/napi/jsnapi_helper.h" 52#include "ecmascript/object_factory.h" 53#include "ecmascript/pgo_profiler/pgo_profiler.h" 54#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 55#include "ecmascript/pgo_profiler/pgo_profiler_encoder.h" 56#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 57#include "ecmascript/tagged_array.h" 58#include "ecmascript/tests/test_helper.h" 59#include "ecmascript/tagged_tree.h" 60#include "ecmascript/weak_vector.h" 61#include "ecmascript/regexp/regexp_parser.h" 62#include "gtest/gtest.h" 63#include "jsnapi_expo.h" 64 65using namespace panda; 66using namespace panda::ecmascript; 67using namespace panda::ecmascript::kungfu; 68 69static constexpr char TEST_CHAR_STRING_FLAGS[] = "gimsuy"; 70static constexpr char TEST_CHAR_STRING_STATE[] = "closed"; 71 72namespace panda::test { 73using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction; 74using PGOProfilerManager = panda::ecmascript::pgo::PGOProfilerManager; 75using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *); 76class JSNApiTests : public testing::Test { 77public: 78 static void SetUpTestCase() 79 { 80 GTEST_LOG_(INFO) << "SetUpTestCase"; 81 } 82 83 static void TearDownTestCase() 84 { 85 GTEST_LOG_(INFO) << "TearDownCase"; 86 } 87 88 void SetUp() override 89 { 90 RuntimeOption option; 91 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR); 92 vm_ = JSNApi::CreateJSVM(option); 93 ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime"; 94 thread_ = vm_->GetJSThread(); 95 vm_->SetEnableForceGC(true); 96 thread_->ManagedCodeBegin(); 97 } 98 99 void TearDown() override 100 { 101 thread_->ManagedCodeEnd(); 102 vm_->SetEnableForceGC(false); 103 JSNApi::DestroyJSVM(vm_); 104 } 105 106 template <typename T> void TestNumberRef(T val, TaggedType expected) 107 { 108 LocalScope scope(vm_); 109 Local<NumberRef> obj = NumberRef::New(vm_, val); 110 ASSERT_TRUE(obj->IsNumber()); 111 JSTaggedType res = JSNApiHelper::ToJSTaggedValue(*obj).GetRawData(); 112 ASSERT_EQ(res, expected); 113 if constexpr (std::is_floating_point_v<T>) { 114 if (std::isnan(val)) { 115 ASSERT_TRUE(std::isnan(obj->Value())); 116 } else { 117 ASSERT_EQ(obj->Value(), val); 118 } 119 } else if constexpr (sizeof(T) >= sizeof(int32_t)) { 120 ASSERT_EQ(obj->IntegerValue(vm_), val); 121 } else if constexpr (std::is_signed_v<T>) { 122 ASSERT_EQ(obj->Int32Value(vm_), val); 123 } else { 124 ASSERT_EQ(obj->Uint32Value(vm_), val); 125 } 126 } 127 128 TaggedType ConvertDouble(double val) 129 { 130 return base::bit_cast<JSTaggedType>(val) + JSTaggedValue::DOUBLE_ENCODE_OFFSET; 131 } 132 133protected: 134 JSThread *thread_ = nullptr; 135 EcmaVM *vm_ = nullptr; 136}; 137 138Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info) 139{ 140 EscapeLocalScope scope(info->GetVM()); 141 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber())); 142} 143 144void WeakRefCallback(EcmaVM *vm) 145{ 146 LocalScope scope(vm); 147 Local<ObjectRef> object = ObjectRef::New(vm); 148 Global<ObjectRef> globalObject(vm, object); 149 globalObject.SetWeak(); 150 Local<ObjectRef> object1 = ObjectRef::New(vm); 151 Global<ObjectRef> globalObject1(vm, object1); 152 globalObject1.SetWeak(); 153 vm->CollectGarbage(TriggerGCType::YOUNG_GC); 154 vm->CollectGarbage(TriggerGCType::OLD_GC); 155 globalObject.FreeGlobalHandleAddr(); 156} 157 158void ThreadCheck(const EcmaVM *vm) 159{ 160 EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId()); 161} 162 163HWTEST_F_L0(JSNApiTests, GetGlobalObject) 164{ 165 LocalScope scope(vm_); 166 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_); 167 ASSERT_FALSE(globalObject.IsEmpty()); 168 ASSERT_TRUE(globalObject->IsObject(vm_)); 169} 170 171HWTEST_F_L0(JSNApiTests, ThreadIdCheck) 172{ 173 EXPECT_TRUE(vm_->GetJSThread()->GetThreadId() == JSThread::GetCurrentThreadId()); 174} 175 176/** 177 * @tc.number: ffi_interface_api_001 178 * @tc.name: RegisterFunction 179 * @tc.desc:Through the FunctionRef:: New method, we can obtain a reference to the function, register and execute it, 180 * confirm that the return value is an array, and the length of the array is the same as the length of 181 * the passed in parameter list. 182 * @tc.type: FUNC 183 * @tc.require: parameter 184 */ 185HWTEST_F_L0(JSNApiTests, RegisterFunction) 186{ 187 LocalScope scope(vm_); 188 Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback); 189 ASSERT_TRUE(!callback.IsEmpty()); 190 std::vector<Local<JSValueRef>> arguments; 191 arguments.emplace_back(JSValueRef::Undefined(vm_)); 192 Local<JSValueRef> result = callback->Call(vm_, JSValueRef::Undefined(vm_), 193 arguments.data(), arguments.size()); 194 ASSERT_TRUE(result->IsArray(vm_)); 195 Local<ArrayRef> array(result); 196 ASSERT_EQ(static_cast<uint64_t>(array->Length(vm_)), arguments.size()); 197} 198 199HWTEST_F_L0(JSNApiTests, GetProperty) 200{ 201 LocalScope scope(vm_); 202 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_); 203 ASSERT_FALSE(globalObject.IsEmpty()); 204 ASSERT_TRUE(globalObject->IsObject(vm_)); 205 206 Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Number"); 207 Local<ObjectRef> property = globalObject->Get(vm_, key); 208 ASSERT_TRUE(property->IsFunction(vm_)); 209} 210 211HWTEST_F_L0(JSNApiTests, SetProperty) 212{ 213 LocalScope scope(vm_); 214 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_); 215 ASSERT_FALSE(globalObject.IsEmpty()); 216 ASSERT_TRUE(globalObject->IsObject(vm_)); 217 218 Local<ArrayRef> property = ArrayRef::New(vm_, 3); // 3 : length 219 ASSERT_TRUE(property->IsArray(vm_)); 220 ASSERT_EQ(property->Length(vm_), 3U); // 3 : test case of input 221 222 Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Test"); 223 bool result = globalObject->Set(vm_, key, property); 224 ASSERT_TRUE(result); 225 226 Local<ObjectRef> propertyGet = globalObject->Get(vm_, key); 227 ASSERT_TRUE(propertyGet->IsArray(vm_)); 228 ASSERT_EQ(Local<ArrayRef>(propertyGet)->Length(vm_), 3U); // 3 : test case of input 229} 230 231/** 232 * @tc.number: ffi_interface_api_002 233 * @tc.name: JsonParser 234 * @tc.desc:Construct a BufferRef function to determine whether it is a Get 235 * @tc.type: FUNC 236 * @tc.require: parameter 237 */ 238HWTEST_F_L0(JSNApiTests, JsonParser) 239{ 240 LocalScope scope(vm_); 241 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_); 242 ASSERT_FALSE(globalObject.IsEmpty()); 243 ASSERT_TRUE(globalObject->IsObject(vm_)); 244 245 const char * const test { R"({"orientation": "portrait"})" }; 246 Local<ObjectRef> jsonString = StringRef::NewFromUtf8(vm_, test); 247 248 Local<JSValueRef> result = JSON::Parse(vm_, jsonString); 249 ASSERT_TRUE(result->IsObject(vm_)); 250 251 Local<ObjectRef> keyString = StringRef::NewFromUtf8(vm_, "orientation"); 252 Local<JSValueRef> property = Local<ObjectRef>(result)->Get(vm_, keyString); 253 ASSERT_TRUE(property->IsString(vm_)); 254} 255 256HWTEST_F_L0(JSNApiTests, StrictEqual) 257{ 258 LocalScope scope(vm_); 259 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1"); 260 Local<StringRef> target1 = StringRef::NewFromUtf8(vm_, "1"); 261 Local<NumberRef> target = NumberRef::New(vm_, 1); 262 263 ASSERT_FALSE(origin->IsStrictEquals(vm_, target)); 264 ASSERT_TRUE(origin->IsStrictEquals(vm_, target1)); 265} 266 267/** 268 * @tc.number: ffi_interface_api_003 269 * @tc.name: InstanceOf 270 * @tc.desc:Verifying whether the InstanceOf method can correctly determine whether an object is an 271 * instance of another object. 272 * @tc.type: FUNC 273 * @tc.require: parameter 274 */ 275HWTEST_F_L0(JSNApiTests, InstanceOf) 276{ 277 LocalScope scope(vm_); 278 Local<FunctionRef> target = FunctionRef::New(vm_, nullptr); 279 Local<ArrayRef> origin = ArrayRef::New(vm_, 1); 280 281 ASSERT_FALSE(origin->InstanceOf(vm_, target)); 282} 283 284HWTEST_F_L0(JSNApiTests, TypeOf) 285{ 286 LocalScope scope(vm_); 287 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1"); 288 Local<StringRef> typeString = origin->Typeof(vm_); 289 ASSERT_EQ(typeString->ToString(vm_), "string"); 290 291 Local<NumberRef> target = NumberRef::New(vm_, 1); 292 typeString = target->Typeof(vm_); 293 ASSERT_EQ(typeString->ToString(vm_), "number"); 294} 295 296/** 297 * @tc.number: ffi_interface_api_004 298 * @tc.name: Symbol 299 * @tc.desc: Determine if it is a symbol type 300 * @tc.type: FUNC 301 * @tc.require: parameter 302 */ 303HWTEST_F_L0(JSNApiTests, Symbol) 304{ 305 LocalScope scope(vm_); 306 Local<StringRef> description = StringRef::NewFromUtf8(vm_, "test"); 307 Local<SymbolRef> symbol = SymbolRef::New(vm_, description); 308 309 ASSERT_FALSE(description->IsSymbol(vm_)); 310 ASSERT_TRUE(symbol->IsSymbol(vm_)); 311} 312 313/** 314 * @tc.number: ffi_interface_api_005 315 * @tc.name: StringUtf8_001 316 * @tc.desc: 317 * Utf8Length:Read the non Chinese value length of StringRef according to utf8 type 318 * WriteUtf8:Write the non Chinese value of StringRef to the char array buffer 319 * @tc.type: FUNC 320 * @tc.require: parameter 321 */ 322HWTEST_F_L0(JSNApiTests, StringUtf8_001) 323{ 324 LocalScope scope(vm_); 325 std::string test = "Hello world"; 326 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str()); 327 328 EXPECT_EQ(testString->Utf8Length(vm_), 12); // 12 : length of testString("Hello World") 329 char buffer[12]; // 12 : length of testString 330 EXPECT_EQ(testString->WriteUtf8(vm_, buffer, 12), 12); // 12 : length of testString("Hello World") 331 std::string res(buffer); 332 ASSERT_EQ(res, test); 333} 334 335/** 336 * @tc.number: ffi_interface_api_006 337 * @tc.name: StringUtf8_002 338 * @tc.desc: 339 * Utf8Length:Read the non Chinese value length of StringRef according to utf8 type 340 * WriteUtf8:Write the non Chinese value of StringRef to the char array buffer 341 * @tc.type: FUNC 342 * @tc.require: parameter 343 */ 344HWTEST_F_L0(JSNApiTests, StringUtf8_002) 345{ 346 LocalScope scope(vm_); 347 std::string test = "年"; 348 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str()); 349 350 EXPECT_EQ(testString->Utf8Length(vm_), 4); // 4 : length of testString("年") 351 char buffer[4]; // 4 : length of testString 352 EXPECT_EQ(testString->WriteUtf8(vm_, buffer, 4), 4); // 4 : length of testString("年") 353 std::string res(buffer); 354 ASSERT_EQ(res, test); 355} 356 357HWTEST_F_L0(JSNApiTests, StringUtf8_003) 358{ 359 LocalScope scope(vm_); 360 std::string str1 = "a"; 361 std::string str2 = "b"; 362 std::string test = str1 + '\0' + str2; 363 364 // isWriteBuffer == false, \u0000 ==> C080 365 Local<StringRef> testString1 = StringRef::NewFromUtf8(vm_, test.c_str(), test.length()); 366 EXPECT_EQ(testString1->Utf8Length(vm_, false), 5); 367 char buffer1[4]; 368 testString1->WriteUtf8(vm_, buffer1, 4, false); 369 EXPECT_EQ(buffer1[0], 'a'); 370 EXPECT_EQ(buffer1[1], '\xC0'); 371 EXPECT_EQ(buffer1[2], '\x80'); 372 EXPECT_EQ(buffer1[3], 'b'); 373 374 // isWriteBuffer == true, \u0000 ==> 0x00U 375 Local<StringRef> testString2 = StringRef::NewFromUtf8(vm_, test.c_str(), test.length()); 376 EXPECT_EQ(testString2->Utf8Length(vm_, true), 4); 377 char buffer2[4]; 378 testString2->WriteUtf8(vm_, buffer2, 4, true); 379 EXPECT_EQ(buffer2[0], 'a'); 380 EXPECT_EQ(buffer2[1], '\0'); 381 EXPECT_EQ(buffer2[2], 'b'); 382} 383 384HWTEST_F_L0(JSNApiTests, StringEncodeIntoUint8_001) { 385 LocalScope scope(vm_); 386 std::string test = ""; 387 388 Local<StringRef> testString1 = 389 StringRef::NewFromUtf8(vm_, test.c_str(), test.length()); 390 Local<TypedArrayRef> typedArray = testString1->EncodeIntoUint8Array(vm_); 391 EXPECT_TRUE(typedArray->IsUndefined()); 392} 393 394HWTEST_F_L0(JSNApiTests, StringEncodeIntoUint8_002) { 395 LocalScope scope(vm_); 396 std::string test = "abc123"; 397 char excepted[7] = {0x61, 0x62, 0x63, 0x31, 0x32, 0x33, 0}; 398 399 Local<StringRef> testString1 = 400 StringRef::NewFromUtf8(vm_, test.c_str(), test.length()); 401 Local<TypedArrayRef> typedArray = testString1->EncodeIntoUint8Array(vm_); 402 403 char *res = reinterpret_cast<char *>(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_)); 404 405 ASSERT_STREQ(res, excepted); 406} 407 408/** 409 * @tc.number: ffi_interface_api_007 410 * @tc.name: StringLatin1_001 411 * @tc.desc: 412 * WriteLatin1:Write the Chinese value of StringRef to the char array buffer 413 * Length:Obtain the length of the Chinese value of StringRef 414 * @tc.type: FUNC 415 * @tc.require: parameter 416 */ 417HWTEST_F_L0(JSNApiTests, StringLatin1_001) 418{ 419 LocalScope scope(vm_); 420 std::string test = "中"; 421 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str()); 422 423 EXPECT_EQ(testString->Length(vm_), 1U); 424 char buffer[1]; 425 EXPECT_EQ(testString->WriteLatin1(vm_, buffer, 1), 1); 426 427 EXPECT_EQ(buffer[0], '-'); // '-' == 0x2D 428} 429 430/** 431 * @tc.number: ffi_interface_api_008 432 * @tc.name: StringLatin1_002 433 * @tc.desc: 434 * WriteLatin1:Write the non Chinese value of StringRef to the char array buffer 435 * Length:Obtain the length of the non Chinese value of StringRef 436 * @tc.type: FUNC 437 * @tc.require: parameter 438 */ 439HWTEST_F_L0(JSNApiTests, StringLatin1_002) 440{ 441 LocalScope scope(vm_); 442 std::string test = "En123"; 443 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str()); 444 445 EXPECT_EQ(testString->Length(vm_), 5U); 446 char buffer[5]; 447 EXPECT_EQ(testString->WriteLatin1(vm_, buffer, 5), 5); 448 449 EXPECT_EQ(buffer[0], 'E'); 450 EXPECT_EQ(buffer[1], 'n'); 451 EXPECT_EQ(buffer[2], '1'); 452 EXPECT_EQ(buffer[3], '2'); 453 EXPECT_EQ(buffer[4], '3'); 454} 455 456/** 457 * @tc.number: ffi_interface_api_009 458 * @tc.name: ToType 459 * @tc.desc: 460 * ToString:Obtain the length of the non Chinese value of StringRef 461 * @tc.type: FUNC 462 * @tc.require: parameter 463 */ 464HWTEST_F_L0(JSNApiTests, ToType) 465{ 466 LocalScope scope(vm_); 467 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3"); 468 Local<JSValueRef> toValue(toString); 469 470 ASSERT_EQ(toString->ToNumber(vm_)->Value(), -123.3); // -123 : test case of input 471 ASSERT_EQ(toString->ToBoolean(vm_)->Value(), true); 472 ASSERT_EQ(toValue->ToString(vm_)->ToString(vm_), "-123.3"); 473 ASSERT_TRUE(toValue->ToObject(vm_)->IsObject(vm_)); 474} 475 476HWTEST_F_L0(JSNApiTests, TypeValue) 477{ 478 LocalScope scope(vm_); 479 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123"); 480 Local<JSValueRef> toValue(toString); 481 482 ASSERT_EQ(toString->Int32Value(vm_), -123); // -123 : test case of input 483 ASSERT_EQ(toString->BooleaValue(vm_), true); 484 ASSERT_EQ(toString->Uint32Value(vm_), 4294967173U); // 4294967173 : test case of input 485 ASSERT_EQ(toString->IntegerValue(vm_), -123); // -123 : test case of input 486} 487 488void *Detach() 489{ 490 GTEST_LOG_(INFO) << "detach is running"; 491 return nullptr; 492} 493 494void Attach([[maybe_unused]] int *buffer) 495{ 496 GTEST_LOG_(INFO) << "attach is running"; 497} 498 499static panda::JSNApi::NativeBindingInfo *CreateNativeBindingInfo(void *attach, void *detach) 500{ 501 GTEST_LOG_(INFO) << "CreateNativeBindingInfo"; 502 panda::JSNApi::NativeBindingInfo *info = panda::JSNApi::NativeBindingInfo::CreateNewInstance(); 503 info->attachData = attach; 504 info->detachData = detach; 505 return info; 506} 507 508HWTEST_F_L0(JSNApiTests, CreateNativeObject) 509{ 510 LocalScope scope(vm_); 511 auto info = CreateNativeBindingInfo(reinterpret_cast<void *>(Attach), reinterpret_cast<void *>(Detach)); 512 size_t nativeBindingSize = 7 * sizeof(void *); // 7 : params num 513 Local<NativePointerRef> nativeInfo = NativePointerRef::New( 514 vm_, reinterpret_cast<void *>(info), 515 []([[maybe_unused]] void *env, void *data, [[maybe_unused]] void *info) { 516 auto externalInfo = reinterpret_cast<panda::JSNApi::NativeBindingInfo *>(data); 517 delete externalInfo; 518 }, 519 nullptr, nativeBindingSize); 520 Local<ObjectRef> object = ObjectRef::New(vm_); 521 bool result = object->ConvertToNativeBindingObject(vm_, nativeInfo); 522 ASSERT_TRUE(result); 523 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 524 Local<JSValueRef> value = ObjectRef::New(vm_); 525 PropertyAttribute attribute(value, true, true, true); 526 527 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute)); 528 Local<JSValueRef> value1 = object->Get(vm_, key); 529 ASSERT_TRUE(value->IsStrictEquals(vm_, value1)); 530 ASSERT_TRUE(object->Has(vm_, key)); 531 ASSERT_TRUE(object->Delete(vm_, key)); 532 ASSERT_FALSE(object->Has(vm_, key)); 533} 534 535/** 536 * @tc.number: ffi_interface_api_010 537 * @tc.name: DefineProperty 538 * @tc.desc: Set Key values and corresponding attribute values 539 * @tc.type: FUNC 540 * @tc.require: parameter 541 */ 542HWTEST_F_L0(JSNApiTests, DefineProperty) 543{ 544 LocalScope scope(vm_); 545 Local<ObjectRef> object = ObjectRef::New(vm_); 546 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 547 Local<JSValueRef> value = ObjectRef::New(vm_); 548 PropertyAttribute attribute(value, true, true, true); 549 550 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute)); 551 Local<JSValueRef> value1 = object->Get(vm_, key); 552 ASSERT_TRUE(value->IsStrictEquals(vm_, value1)); 553} 554 555HWTEST_F_L0(JSNApiTests, HasProperty) 556{ 557 LocalScope scope(vm_); 558 Local<ObjectRef> object = ObjectRef::New(vm_); 559 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 560 Local<JSValueRef> value = ObjectRef::New(vm_); 561 PropertyAttribute attribute(value, true, true, true); 562 563 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute)); 564 ASSERT_TRUE(object->Has(vm_, key)); 565} 566 567HWTEST_F_L0(JSNApiTests, DeleteProperty) 568{ 569 LocalScope scope(vm_); 570 Local<ObjectRef> object = ObjectRef::New(vm_); 571 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 572 Local<JSValueRef> value = ObjectRef::New(vm_); 573 PropertyAttribute attribute(value, true, true, true); 574 575 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute)); 576 ASSERT_TRUE(object->Delete(vm_, key)); 577 ASSERT_FALSE(object->Has(vm_, key)); 578} 579 580/** 581 * @tc.number: ffi_interface_api_011 582 * @tc.name: GetProtoType 583 * @tc.desc:Verify that the GetPrototype method correctly returns the prototype of the function or object, 584 * and verify that the returned prototype is of an object type. 585 * @tc.type: FUNC 586 * @tc.require: parameter 587 */ 588HWTEST_F_L0(JSNApiTests, GetProtoType) 589{ 590 LocalScope scope(vm_); 591 Local<FunctionRef> function = FunctionRef::New(vm_, nullptr); 592 Local<JSValueRef> protoType = function->GetPrototype(vm_); 593 ASSERT_TRUE(protoType->IsObject(vm_)); 594 595 Local<FunctionRef> object = ObjectRef::New(vm_); 596 protoType = object->GetPrototype(vm_); 597 ASSERT_TRUE(protoType->IsObject(vm_)); 598 599 auto info = CreateNativeBindingInfo(reinterpret_cast<void *>(Attach), reinterpret_cast<void *>(Detach)); 600 size_t nativeBindingSize = 7 * sizeof(void *); // 7 : params num 601 Local<NativePointerRef> nativeInfo = NativePointerRef::New( 602 vm_, reinterpret_cast<void *>(info), 603 []([[maybe_unused]] void *env, void *data, [[maybe_unused]] void *info) { 604 auto externalInfo = reinterpret_cast<panda::JSNApi::NativeBindingInfo *>(data); 605 delete externalInfo; 606 }, 607 nullptr, nativeBindingSize); 608 bool result = object->ConvertToNativeBindingObject(vm_, nativeInfo); 609 ASSERT_TRUE(result); 610 protoType = object->GetPrototype(vm_); 611 ASSERT_TRUE(protoType->IsObject(vm_)); 612} 613 614/* 615 * @tc.number: ffi_interface_api_012 616 * @tc.name: CheckReject 617 * @tc.desc: The function of CheckReject is similar to that of CheckResolve, 618 * but it is used to check whether a function call provides the correct cause of the error, 619 * which is achieved through ASSERT_ EQ (Local<StringRef>(reason) ->ToString(vm_), 620 * check if the value of this string is equal to "Reject". 621 * @tc.type: FUNC 622 * @tc.require: parameter info 623 */ 624void CheckReject(JsiRuntimeCallInfo *info) 625{ 626 ASSERT_EQ(info->GetArgsNumber(), 1U); 627 Local<JSValueRef> reason = info->GetCallArgRef(0); 628 ASSERT_TRUE(reason->IsString(info->GetVM())); 629 ASSERT_EQ(Local<StringRef>(reason)->ToString(info->GetVM()), "Reject"); 630} 631 632Local<JSValueRef> RejectCallback(JsiRuntimeCallInfo *info) 633{ 634 LocalScope scope(info->GetVM()); 635 CheckReject(info); 636 return JSValueRef::Undefined(info->GetVM()); 637} 638 639HWTEST_F_L0(JSNApiTests, PromiseCatch) 640{ 641 LocalScope scope(vm_); 642 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 643 644 Local<PromiseRef> promise = capability->GetPromise(vm_); 645 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback); 646 Local<PromiseRef> catchPromise = promise->Catch(vm_, reject); 647 ASSERT_TRUE(promise->IsPromise(vm_)); 648 ASSERT_TRUE(catchPromise->IsPromise(vm_)); 649 650 Local<StringRef> reason = StringRef::NewFromUtf8(vm_, "Reject"); 651 ASSERT_TRUE(capability->Reject(vm_, reason)); 652 653 vm_->GetJSThread()->GetCurrentEcmaContext()->ExecutePromisePendingJob(); 654} 655 656HWTEST_F_L0(JSNApiTests, PromiseCatchUintPtr) 657{ 658 LocalScope scope(vm_); 659 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 660 661 Local<PromiseRef> promise = capability->GetPromise(vm_); 662 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback); 663 Local<PromiseRef> catchPromise = promise->Catch(vm_, reject); 664 ASSERT_TRUE(promise->IsPromise(vm_)); 665 ASSERT_TRUE(catchPromise->IsPromise(vm_)); 666 667 Local<StringRef> reason = StringRef::NewFromUtf8(vm_, "Reject"); 668 ASSERT_TRUE(capability->Reject(vm_, reinterpret_cast<uintptr_t>(*reason))); 669 670 vm_->GetJSThread()->GetCurrentEcmaContext()->ExecutePromisePendingJob(); 671} 672 673/* 674 * @tc.number: ffi_interface_api_013 675 * @tc.name: CheckResolve_New_Reject 676 * @tc.desc: Verify whether a specific function call provided the correct parameters (a number 300.3), 677 * where ASSERT_ TRUE (value ->IsNumber()) Check if this parameter is a number. 678 * New:Used to verify whether the creation of a new PromiseCapabilityRef object was successful. 679 * Reject:Used to verify whether the reason for rejecting the Promise object was successfully obtained. 680 * @tc.type: FUNC 681 * @tc.require: parameter info 682 */ 683void CheckResolve(JsiRuntimeCallInfo *info) 684{ 685 ASSERT_EQ(info->GetArgsNumber(), 1U); 686 Local<JSValueRef> value = info->GetCallArgRef(0); 687 ASSERT_TRUE(value->IsNumber()); 688 ASSERT_EQ(Local<NumberRef>(value)->Value(), 300.3); // 300.3 : test case of input 689} 690 691Local<JSValueRef> ResolvedCallback(JsiRuntimeCallInfo *info) 692{ 693 LocalScope scope(info->GetVM()); 694 CheckResolve(info); 695 return JSValueRef::Undefined(info->GetVM()); 696} 697 698HWTEST_F_L0(JSNApiTests, PromiseThen) 699{ 700 LocalScope scope(vm_); 701 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 702 703 Local<PromiseRef> promise = capability->GetPromise(vm_); 704 Local<FunctionRef> resolve = FunctionRef::New(vm_, ResolvedCallback); 705 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback); 706 Local<PromiseRef> thenPromise = promise->Then(vm_, resolve, reject); 707 ASSERT_TRUE(promise->IsPromise(vm_)); 708 ASSERT_TRUE(thenPromise->IsPromise(vm_)); 709 710 Local<StringRef> value = NumberRef::New(vm_, 300.3); // 300.3 : test case of input 711 ASSERT_TRUE(capability->Resolve(vm_, value)); 712 vm_->GetJSThread()->GetCurrentEcmaContext()->ExecutePromisePendingJob(); 713} 714 715HWTEST_F_L0(JSNApiTests, PromiseThenUintPtr) 716{ 717 LocalScope scope(vm_); 718 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 719 720 Local<PromiseRef> promise = capability->GetPromise(vm_); 721 Local<FunctionRef> resolve = FunctionRef::New(vm_, ResolvedCallback); 722 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback); 723 Local<PromiseRef> thenPromise = promise->Then(vm_, resolve, reject); 724 ASSERT_TRUE(promise->IsPromise(vm_)); 725 ASSERT_TRUE(thenPromise->IsPromise(vm_)); 726 727 Local<StringRef> value = NumberRef::New(vm_, 300.3); // 300.3 : test case of input 728 ASSERT_TRUE(capability->Resolve(vm_, reinterpret_cast<uintptr_t>(*value))); 729 vm_->GetJSThread()->GetCurrentEcmaContext()->ExecutePromisePendingJob(); 730} 731 732/** 733 * @tc.number: ffi_interface_api_014 734 * @tc.name: Constructor_IsObject 735 * @tc.desc: Used to verify whether the creation of a new PromiseCapabilityRef object was successful. 736 * Used to verify whether obtaining a PromiseRef object was successful. 737 IsObject:Determine if it is an object 738 * @tc.type: FUNC 739 * @tc.require: parameter isobject 740 */ 741HWTEST_F_L0(JSNApiTests, Constructor_IsObject) 742{ 743 LocalScope scope(vm_); 744 Local<ObjectRef> object = JSNApi::GetGlobalObject(vm_); 745 Local<StringRef> key = StringRef::NewFromUtf8(vm_, "Number"); 746 Local<FunctionRef> numberConstructor = object->Get(vm_, key); 747 Local<JSValueRef> argv[1]; 748 argv[0] = NumberRef::New(vm_, 1.3); // 1.3 : test case of input 749 Local<JSValueRef> result = numberConstructor->Constructor(vm_, argv, 1); 750 ASSERT_TRUE(result->IsObject(vm_)); 751 ASSERT_EQ(result->ToNumber(vm_)->Value(), 1.3); // 1.3 : size of arguments 752} 753 754/** 755 * @tc.number: ffi_interface_api_015 756 * @tc.name: Constructor_IsBuffer 757 * @tc.desc: Construct a BufferRef function to determine whether it is a Buffer. 758 * The constructor used to verify the success of the FunctionRef class. 759 * @tc.type: FUNC 760 * @tc.require: parameter parameter 761 */ 762HWTEST_F_L0(JSNApiTests, ArrayBuffer) 763{ 764 LocalScope scope(vm_); 765 const int32_t length = 15; 766 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 767 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 768 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length); 769 ASSERT_NE(arrayBuffer->GetBuffer(vm_), nullptr); 770 JSNApi::TriggerGC(vm_); 771} 772 773HWTEST_F_L0(JSNApiTests, ArrayBufferWithBuffer) 774{ 775 static bool isFree = false; 776 struct Data { 777 int32_t length; 778 }; 779 const int32_t length = 15; 780 Data *data = new Data(); 781 data->length = length; 782 NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void { 783 delete[] reinterpret_cast<uint8_t *>(buffer); 784 Data *currentData = reinterpret_cast<Data *>(data); 785 ASSERT_EQ(currentData->length, 15); // 5 : size of arguments 786 delete currentData; 787 isFree = true; 788 }; 789 { 790 LocalScope scope(vm_); 791 uint8_t *buffer = new uint8_t[length](); 792 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data); 793 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 794 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length); 795 ASSERT_EQ(arrayBuffer->GetBuffer(vm_), buffer); 796 } 797 JSNApi::TriggerGC(vm_, JSNApi::TRIGGER_GC_TYPE::FULL_GC); 798 ASSERT_TRUE(isFree); 799} 800 801HWTEST_F_L0(JSNApiTests, DataView) 802{ 803 LocalScope scope(vm_); 804 const int32_t length = 15; 805 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 806 JSNApi::TriggerGC(vm_); 807 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 808 809 // 5 : offset of byte, 7 : length 810 Local<DataViewRef> dataView = DataViewRef::New(vm_, arrayBuffer, 5, 7); 811 ASSERT_TRUE(dataView->IsDataView(vm_)); 812 ASSERT_EQ(dataView->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 813 ASSERT_EQ(dataView->ByteLength(), 7U); // 7 : size of arguments 814 ASSERT_EQ(dataView->ByteOffset(), 5U); // 5 : size of arguments 815 816 // 5 : offset of byte, 11 : length 817 dataView = DataViewRef::New(vm_, arrayBuffer, 5, 11); 818 ASSERT_TRUE(dataView->IsUndefined()); 819} 820 821/** 822 * @tc.number: ffi_interface_api_016 823 * @tc.name: Int8Array_IsUndefined 824 * @tc.desc:Using the functions of Int8Array and verifying if its attribute values are correct. 825 * Used to determine whether a given object represents an undefined value. 826 Determine if it is an int8 array. 827 * @tc.type: FUNC 828 * @tc.require: parameter 829 */ 830HWTEST_F_L0(JSNApiTests, Int8Array) 831{ 832 LocalScope scope(vm_); 833 const int32_t length = 15; 834 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 835 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 836 837 // 5 : offset of byte, 6 : length 838 Local<Int8ArrayRef> typedArray = Int8ArrayRef::New(vm_, arrayBuffer, 5, 6); 839 ASSERT_TRUE(typedArray->IsInt8Array(vm_)); 840 ASSERT_EQ(typedArray->ByteLength(vm_), 6U); // 6 : length of bytes 841 ASSERT_EQ(typedArray->ByteOffset(vm_), 5U); // 5 : offset of byte 842 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 843 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 844} 845 846/** 847 * @tc.number: ffi_interface_api_017 848 * @tc.name: Uint8Array_ ByteLength_ByteOffset_ArrayLength_GetArrayBuffer 849 * @tc.desc:Using the functions of Uint8Array and verifying if its attribute values are correct. 850 * Used to verify whether the length, offset, array length, and associated 851 * ArrayBufferRef object of the bytes obtained from the array were successful. 852 * @tc.type: FUNC 853 * @tc.require: parameter 854 */ 855HWTEST_F_L0(JSNApiTests, Uint8Array) 856{ 857 LocalScope scope(vm_); 858 const int32_t length = 15; 859 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 860 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 861 862 // 5 : offset of byte, 6 : length 863 Local<Uint8ArrayRef> typedArray = Uint8ArrayRef::New(vm_, arrayBuffer, 5, 6); 864 ASSERT_TRUE(typedArray->IsUint8Array(vm_)); 865 ASSERT_EQ(typedArray->ByteLength(vm_), 6U); // 6 : length of bytes 866 ASSERT_EQ(typedArray->ByteOffset(vm_), 5U); // 5 : offset of byte 867 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 868 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 869} 870 871/** 872 * @tc.number: ffi_interface_api_018 873 * @tc.name: Uint8ClampedArray 874 * @tc.desc:Using the functions of Uint8ClampedArray and verifying if its attribute values are correct. 875 * @tc.type: FUNC 876 * @tc.require: parameter 877 */ 878HWTEST_F_L0(JSNApiTests, Uint8ClampedArray) 879{ 880 LocalScope scope(vm_); 881 const int32_t length = 15; 882 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 883 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 884 885 // 5 : offset of byte, 6 : length 886 Local<Uint8ClampedArrayRef> typedArray = Uint8ClampedArrayRef::New(vm_, arrayBuffer, 5, 6); 887 ASSERT_TRUE(typedArray->IsUint8ClampedArray(vm_)); 888 ASSERT_EQ(typedArray->ByteLength(vm_), 6U); // 6 : length of bytes 889 ASSERT_EQ(typedArray->ByteOffset(vm_), 5U); // 5 : offset of byte 890 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 891 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 892} 893 894/** 895 * @tc.number: ffi_interface_api_019 896 * @tc.name: Int16Array 897 * @tc.desc:Using the functions of Int16Array and verifying if its attribute values are correct. 898 * @tc.type: FUNC 899 * @tc.require: parameter 900 */ 901HWTEST_F_L0(JSNApiTests, Int16Array) 902{ 903 LocalScope scope(vm_); 904 const int32_t length = 30; 905 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 906 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 907 908 // 4 : offset of byte, 6 : length 909 Local<Int16ArrayRef> typedArray = Int16ArrayRef::New(vm_, arrayBuffer, 4, 6); 910 ASSERT_TRUE(typedArray->IsInt16Array(vm_)); 911 ASSERT_EQ(typedArray->ByteLength(vm_), 12U); // 12 : length of bytes 912 ASSERT_EQ(typedArray->ByteOffset(vm_), 4U); // 4 : offset of byte 913 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 914 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 915} 916 917/** 918 * @tc.number: ffi_interface_api_020 919 * @tc.name: Uint16Array 920 * @tc.desc:Using the functions of Uint16Array and verifying if its attribute values are correct. 921 * @tc.type: FUNC 922 * @tc.require: parameter 923 */ 924HWTEST_F_L0(JSNApiTests, Uint16Array) 925{ 926 LocalScope scope(vm_); 927 const int32_t length = 30; 928 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 929 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 930 931 // 4 : offset of byte, 6 : length 932 Local<Uint16ArrayRef> typedArray = Uint16ArrayRef::New(vm_, arrayBuffer, 4, 6); 933 ASSERT_TRUE(typedArray->IsUint16Array(vm_)); 934 ASSERT_EQ(typedArray->ByteLength(vm_), 12U); // 12 : length of bytes 935 ASSERT_EQ(typedArray->ByteOffset(vm_), 4U); // 4 : offset of byte 936 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 937 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 938} 939 940/* 941 * @tc.number: ffi_interface_api_021 942 * @tc.name: Uint32Array 943 * @tc.desc: Verify that the Uint32Array method correctly created a Uint32Array with the specified length and offset, 944 * and verify that its attribute values match expectations. 945 * @tc.type: FUNC 946 * @tc.require: parameter 947 */ 948HWTEST_F_L0(JSNApiTests, Uint32Array) 949{ 950 LocalScope scope(vm_); 951 const int32_t length = 30; 952 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 953 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 954 955 // 4 : offset of byte, 6 : length 956 Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, 4, 6); 957 ASSERT_TRUE(typedArray->IsUint32Array(vm_)); 958 ASSERT_EQ(typedArray->ByteLength(vm_), 24U); // 24 : length of bytes 959 ASSERT_EQ(typedArray->ByteOffset(vm_), 4U); // 4 : offset of byte 960 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 961 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 962} 963 964/** 965 * @tc.number: ffi_interface_api_022 966 * @tc.name: Int32Array 967 * @tc.desc:Using the functions of Int32Array and verifying if its attribute values are correct. 968 * @tc.type: FUNC 969 * @tc.require: parameter 970 */ 971HWTEST_F_L0(JSNApiTests, Int32Array) 972{ 973 LocalScope scope(vm_); 974 const int32_t length = 30; 975 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 976 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 977 978 // 4 : offset of byte, 6 : length 979 Local<Int32ArrayRef> typedArray = Int32ArrayRef::New(vm_, arrayBuffer, 4, 6); 980 ASSERT_TRUE(typedArray->IsInt32Array(vm_)); 981 ASSERT_EQ(typedArray->ByteLength(vm_), 24U); // 24 : length of bytes 982 ASSERT_EQ(typedArray->ByteOffset(vm_), 4U); // 4 : offset of byte 983 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 984 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 985} 986 987HWTEST_F_L0(JSNApiTests, Float32Array) 988{ 989 LocalScope scope(vm_); 990 const int32_t length = 30; 991 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 992 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 993 994 // 4 : offset of byte, 6 : length 995 Local<Float32ArrayRef> typedArray = Float32ArrayRef::New(vm_, arrayBuffer, 4, 6); 996 ASSERT_TRUE(typedArray->IsFloat32Array(vm_)); 997 ASSERT_EQ(typedArray->ByteLength(vm_), 24U); // 24 : length of bytes 998 ASSERT_EQ(typedArray->ByteOffset(vm_), 4U); // 4 : offset of byte 999 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 1000 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 1001} 1002 1003HWTEST_F_L0(JSNApiTests, Float64Array) 1004{ 1005 LocalScope scope(vm_); 1006 const int32_t length = 57; 1007 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 1008 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 1009 1010 // 8 : offset of byte, 6 : length 1011 Local<Float64ArrayRef> typedArray = Float64ArrayRef::New(vm_, arrayBuffer, 8, 6); 1012 ASSERT_TRUE(typedArray->IsFloat64Array(vm_)); 1013 ASSERT_EQ(typedArray->ByteLength(vm_), 48U); // 48 : length of bytes 1014 ASSERT_EQ(typedArray->ByteOffset(vm_), 8U); // 8 : offset of byte 1015 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 1016 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 1017} 1018 1019HWTEST_F_L0(JSNApiTests, BigInt64Array) 1020{ 1021 LocalScope scope(vm_); 1022 const int32_t length = 57; 1023 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 1024 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 1025 1026 // 8 : offset of byte, 6 : length 1027 Local<BigInt64ArrayRef> typedArray = BigInt64ArrayRef::New(vm_, arrayBuffer, 8, 6); 1028 ASSERT_TRUE(typedArray->IsBigInt64Array(vm_)); 1029 ASSERT_EQ(typedArray->ByteLength(vm_), 48U); // 48 : length of bytes 1030 ASSERT_EQ(typedArray->ByteOffset(vm_), 8U); // 8 : offset of byte 1031 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 1032 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 1033} 1034 1035/** 1036 * @tc.number: ffi_interface_api_023 1037 * @tc.name: IsBigInt64Array 1038 * @tc.desc: Used to determine whether a given object is a BigInt64Array. 1039 * @tc.type: FUNC 1040 * @tc.require: parameter 1041 */ 1042HWTEST_F_L0(JSNApiTests, BigUint64Array) 1043{ 1044 LocalScope scope(vm_); 1045 const int32_t length = 57; 1046 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 1047 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 1048 1049 // 8 : offset of byte, 6 : length 1050 Local<BigUint64ArrayRef> typedArray = BigUint64ArrayRef::New(vm_, arrayBuffer, 8, 6); 1051 ASSERT_TRUE(typedArray->IsBigUint64Array(vm_)); 1052 ASSERT_EQ(typedArray->ByteLength(vm_), 48U); // 48 : length of bytes 1053 ASSERT_EQ(typedArray->ByteOffset(vm_), 8U); // 8 : offset of byte 1054 ASSERT_EQ(typedArray->ArrayLength(vm_), 6U); // 6 : length of array 1055 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 1056} 1057 1058/** 1059 * @tc.number: ffi_interface_api_024 1060 * @tc.name: Error_ThrowException_HasPendingException 1061 * @tc.desc: 1062 * Error:Build error message 1063 * ThrowException:Throw an exception, error is the exception information 1064 * HasPendingException:Determine if there are any uncaught exceptions 1065 * @tc.type: FUNC 1066 * @tc.require: parameter 1067 */ 1068HWTEST_F_L0(JSNApiTests, Error_ThrowException_HasPendingException) 1069{ 1070 LocalScope scope(vm_); 1071 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1072 Local<JSValueRef> error = Exception::Error(vm_, message); 1073 ASSERT_TRUE(error->IsError(vm_)); 1074 1075 JSNApi::ThrowException(vm_, error); 1076 ASSERT_TRUE(thread_->HasPendingException()); 1077} 1078 1079HWTEST_F_L0(JSNApiTests, RangeError) 1080{ 1081 LocalScope scope(vm_); 1082 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1083 Local<JSValueRef> error = Exception::RangeError(vm_, message); 1084 ASSERT_TRUE(error->IsError(vm_)); 1085 1086 JSNApi::ThrowException(vm_, error); 1087 ASSERT_TRUE(thread_->HasPendingException()); 1088} 1089 1090/** 1091 * @tc.number: ffi_interface_api_025 1092 * @tc.name: TypeError 1093 * @tc.desc:Tested the ability to create and throw a type error exception, and verified whether the exception 1094 * was correctly recognized and handled. 1095 * @tc.type: FUNC 1096 * @tc.require: parameter 1097 */ 1098HWTEST_F_L0(JSNApiTests, TypeError) 1099{ 1100 LocalScope scope(vm_); 1101 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1102 Local<JSValueRef> error = Exception::TypeError(vm_, message); 1103 ASSERT_TRUE(error->IsError(vm_)); 1104 1105 JSNApi::ThrowException(vm_, error); 1106 ASSERT_TRUE(thread_->HasPendingException()); 1107} 1108 1109HWTEST_F_L0(JSNApiTests, ReferenceError) 1110{ 1111 LocalScope scope(vm_); 1112 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1113 Local<JSValueRef> error = Exception::ReferenceError(vm_, message); 1114 ASSERT_TRUE(error->IsError(vm_)); 1115 1116 JSNApi::ThrowException(vm_, error); 1117 ASSERT_TRUE(thread_->HasPendingException()); 1118} 1119 1120HWTEST_F_L0(JSNApiTests, SyntaxError) 1121{ 1122 LocalScope scope(vm_); 1123 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1124 Local<JSValueRef> error = Exception::SyntaxError(vm_, message); 1125 ASSERT_TRUE(error->IsError(vm_)); 1126 1127 JSNApi::ThrowException(vm_, error); 1128 ASSERT_TRUE(thread_->HasPendingException()); 1129} 1130 1131/** 1132 * @tc.number: ffi_interface_api_026 1133 * @tc.name: OOMError 1134 * @tc.desc:Create and throw a memory overflow error exception function, and verify 1135 * whether the exception is correctly recognized and handled. 1136 * @tc.type: FUNC 1137 * @tc.require: parameter 1138 */ 1139HWTEST_F_L0(JSNApiTests, OOMError) 1140{ 1141 LocalScope scope(vm_); 1142 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest"); 1143 Local<JSValueRef> error = Exception::OOMError(vm_, message); 1144 ASSERT_TRUE(error->IsError(vm_)); 1145 1146 JSNApi::ThrowException(vm_, error); 1147 ASSERT_TRUE(thread_->HasPendingException()); 1148} 1149 1150HWTEST_F_L0(JSNApiTests, InheritPrototype_001) 1151{ 1152 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1153 LocalScope scope(vm_); 1154 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 1155 // new with Builtins::Set Prototype 1156 JSHandle<JSTaggedValue> set = env->GetBuiltinsSetFunction(); 1157 Local<FunctionRef> setLocal = JSNApiHelper::ToLocal<FunctionRef>(set); 1158 // new with Builtins::Map Prototype 1159 JSHandle<JSTaggedValue> map = env->GetBuiltinsMapFunction(); 1160 Local<FunctionRef> mapLocal = JSNApiHelper::ToLocal<FunctionRef>(map); 1161 JSHandle<JSTaggedValue> setPrototype(thread_, JSHandle<JSFunction>::Cast(set)->GetFunctionPrototype()); 1162 JSHandle<JSTaggedValue> mapPrototype(thread_, JSHandle<JSFunction>::Cast(map)->GetFunctionPrototype()); 1163 JSHandle<JSTaggedValue> mapPrototypeProto(thread_, JSTaggedValue::GetPrototype(thread_, mapPrototype)); 1164 bool same = JSTaggedValue::SameValue(setPrototype, mapPrototypeProto); 1165 // before inherit, map.Prototype.__proto__ should be different from set.Prototype 1166 ASSERT_FALSE(same); 1167 // before inherit, map.__proto__ should be different from set 1168 JSHandle<JSTaggedValue> mapProto(thread_, JSTaggedValue::GetPrototype(thread_, map)); 1169 bool same1 = JSTaggedValue::SameValue(set, mapProto); 1170 ASSERT_FALSE(same1); 1171 1172 // Set property to Set Function 1173 auto factory = vm_->GetFactory(); 1174 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString(); 1175 PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString); 1176 bool success = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), defaultString, desc); 1177 ASSERT_TRUE(success); 1178 JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromASCII("property1").GetTaggedValue()); 1179 JSHandle<JSTaggedValue> func = env->GetTypedArrayFunction(); 1180 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func); 1181 bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), property1String, desc1); 1182 ASSERT_TRUE(success1); 1183 1184 mapLocal->Inherit(vm_, setLocal); 1185 JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(mapLocal); 1186 JSHandle<JSTaggedValue> sonPrototype(thread_, JSHandle<JSFunction>::Cast(sonHandle)->GetFunctionPrototype()); 1187 JSHandle<JSTaggedValue> sonPrototypeProto(thread_, JSTaggedValue::GetPrototype(thread_, sonPrototype)); 1188 bool same2 = JSTaggedValue::SameValue(setPrototype, sonPrototypeProto); 1189 ASSERT_TRUE(same2); 1190 JSHandle<JSTaggedValue> sonProto(thread_, JSTaggedValue::GetPrototype(thread_, map)); 1191 bool same3 = JSTaggedValue::SameValue(set, sonProto); 1192 ASSERT_TRUE(same3); 1193 1194 // son = new Son(), Son() inherit from Parent(), Test whether son.InstanceOf(Parent) is true 1195 JSHandle<JSObject> sonObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle); 1196 bool isInstance = JSObject::InstanceOf(thread_, JSHandle<JSTaggedValue>::Cast(sonObj), set); 1197 ASSERT_TRUE(isInstance); 1198 1199 // Test whether son Function can access to property of parent Function 1200 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), defaultString); 1201 bool same4 = JSTaggedValue::SameValue(defaultString, res.GetValue()); 1202 ASSERT_TRUE(same4); 1203 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), property1String); 1204 bool same5 = JSTaggedValue::SameValue(func, res1.GetValue()); 1205 ASSERT_TRUE(same5); 1206 1207 // new with empty Function Constructor 1208 Local<FunctionRef> son1 = FunctionRef::New(vm_, FunctionCallback, nullptr); 1209 son1->Inherit(vm_, mapLocal); 1210 JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(son1)); 1211 ASSERT_TRUE(son1Handle->HasFunctionPrototype()); 1212} 1213 1214HWTEST_F_L0(JSNApiTests, InheritPrototype_002) 1215{ 1216 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1217 LocalScope scope(vm_); 1218 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 1219 // new with Builtins::weakSet Prototype 1220 JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction(); 1221 Local<FunctionRef> weakSetLocal = JSNApiHelper::ToLocal<FunctionRef>(weakSet); 1222 // new with Builtins::weakMap Prototype 1223 JSHandle<JSTaggedValue> weakMap = env->GetBuiltinsWeakMapFunction(); 1224 Local<FunctionRef> weakMapLocal = JSNApiHelper::ToLocal<FunctionRef>(weakMap); 1225 1226 weakMapLocal->Inherit(vm_, weakSetLocal); 1227 1228 auto factory = vm_->GetFactory(); 1229 JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromASCII("property1").GetTaggedValue()); 1230 JSHandle<JSTaggedValue> func = env->GetArrayFunction(); 1231 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func); 1232 bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(weakMap), property1String, desc1); 1233 ASSERT_TRUE(success1); 1234 1235 JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(weakMapLocal); 1236 JSHandle<JSObject> sonObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle); 1237 1238 JSHandle<JSTaggedValue> fatherHandle = JSNApiHelper::ToJSHandle(weakSetLocal); 1239 JSHandle<JSObject> fatherObj = 1240 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(fatherHandle), fatherHandle); 1241 1242 JSHandle<JSTaggedValue> sonMethod = JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(sonObj), property1String); 1243 JSHandle<JSTaggedValue> fatherMethod = 1244 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(fatherObj), property1String); 1245 bool same = JSTaggedValue::SameValue(sonMethod, fatherMethod); 1246 ASSERT_TRUE(same); 1247} 1248 1249HWTEST_F_L0(JSNApiTests, InheritPrototype_003) 1250{ 1251 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1252 LocalScope scope(vm_); 1253 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 1254 auto factory = vm_->GetFactory(); 1255 1256 JSHandle<Method> invokeSelf = 1257 factory->NewMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf)); 1258 // father type 1259 JSHandle<JSHClass> protoClass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto()); 1260 JSHandle<JSFunction> protoFunc = factory->NewJSFunctionByHClass(invokeSelf, protoClass); 1261 Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc)); 1262 // son type 1263 JSHandle<JSHClass> noProtoClass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto()); 1264 JSHandle<JSFunction> noProtoFunc = factory->NewJSFunctionByHClass(invokeSelf, noProtoClass); 1265 Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc)); 1266 1267 JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal)); 1268 EXPECT_FALSE(sonHandle->HasFunctionPrototype()); 1269 1270 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString(); 1271 PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString); 1272 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), defaultString, desc); 1273 1274 noProtoLocal->Inherit(vm_, protoLocal); 1275 JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal)); 1276 EXPECT_TRUE(son1Handle->HasFunctionPrototype()); 1277 1278 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), defaultString); 1279 EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res.GetValue()), true); 1280 1281 JSHandle<JSTaggedValue> propertyString(thread_, factory->NewFromASCII("property").GetTaggedValue()); 1282 JSHandle<JSTaggedValue> func = env->GetArrayFunction(); 1283 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func); 1284 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), propertyString, desc1); 1285 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), propertyString); 1286 EXPECT_EQ(JSTaggedValue::SameValue(func, res1.GetValue()), true); 1287} 1288 1289HWTEST_F_L0(JSNApiTests, InheritPrototype_004) 1290{ 1291 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1292 LocalScope scope(vm_); 1293 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 1294 auto factory = vm_->GetFactory(); 1295 1296 JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction(); 1297 JSHandle<JSTaggedValue> deleteString(factory->NewFromASCII("delete")); 1298 JSHandle<JSTaggedValue> addString(factory->NewFromASCII("add")); 1299 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString(); 1300 JSHandle<JSTaggedValue> deleteMethod = JSObject::GetMethod(thread_, weakSet, deleteString); 1301 JSHandle<JSTaggedValue> addMethod = JSObject::GetMethod(thread_, weakSet, addString); 1302 1303 JSHandle<Method> invokeSelf = 1304 factory->NewMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf)); 1305 JSHandle<Method> ctor = 1306 factory->NewMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionConstructor)); 1307 1308 JSHandle<JSHClass> protoClass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto()); 1309 JSHandle<JSFunction> funcFuncPrototype = factory->NewJSFunctionByHClass(invokeSelf, protoClass); 1310 // add method in funcPrototype 1311 PropertyDescriptor desc = PropertyDescriptor(thread_, deleteMethod); 1312 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(funcFuncPrototype), deleteString, desc); 1313 JSHandle<JSTaggedValue> funcFuncPrototypeValue(funcFuncPrototype); 1314 1315 JSHandle<JSHClass> funcFuncProtoIntanceClass = 1316 factory->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncPrototypeValue); 1317 // new with NewJSFunctionByHClass::function Class 1318 JSHandle<JSFunction> protoFunc = factory->NewJSFunctionByHClass(ctor, funcFuncProtoIntanceClass); 1319 EXPECT_TRUE(*protoFunc != nullptr); 1320 // add method in funcnction 1321 PropertyDescriptor desc1 = PropertyDescriptor(thread_, addMethod); 1322 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), addString, desc1); 1323 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), deleteString, desc); 1324 // father type 1325 Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc)); 1326 1327 JSHandle<JSHClass> noProtoClass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto()); 1328 JSHandle<JSFunction> funcFuncNoProtoPrototype = factory->NewJSFunctionByHClass(invokeSelf, noProtoClass); 1329 JSHandle<JSTaggedValue> funcFuncNoProtoPrototypeValue(funcFuncNoProtoPrototype); 1330 1331 JSHandle<JSHClass> funcFuncNoProtoProtoIntanceClass = 1332 factory->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncNoProtoPrototypeValue); 1333 // new with NewJSFunctionByHClass::function Class 1334 JSHandle<JSFunction> noProtoFunc = factory->NewJSFunctionByHClass(ctor, funcFuncNoProtoProtoIntanceClass); 1335 EXPECT_TRUE(*noProtoFunc != nullptr); 1336 // set property that has same key with fater type 1337 PropertyDescriptor desc2 = PropertyDescriptor(thread_, defaultString); 1338 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(noProtoFunc), addString, desc2); 1339 // son type 1340 Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc)); 1341 1342 noProtoLocal->Inherit(vm_, protoLocal); 1343 1344 JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal)); 1345 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), deleteString); 1346 EXPECT_EQ(JSTaggedValue::SameValue(deleteMethod, res.GetValue()), true); 1347 // test if the property value changed after inherit 1348 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), addString); 1349 EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res1.GetValue()), true); 1350} 1351 1352HWTEST_F_L0(JSNApiTests, ClassFunction) 1353{ 1354 LocalScope scope(vm_); 1355 Local<FunctionRef> cls = FunctionRef::NewClassFunction(vm_, FunctionCallback, nullptr, nullptr); 1356 1357 JSHandle<JSTaggedValue> clsObj = JSNApiHelper::ToJSHandle(Local<JSValueRef>(cls)); 1358 ASSERT_TRUE(clsObj->IsClassConstructor()); 1359 1360 JSTaggedValue accessor = 1361 JSHandle<JSFunction>(clsObj)->GetPropertyInlinedProps(JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX); 1362 ASSERT_TRUE(accessor.IsInternalAccessor()); 1363 1364 accessor = JSHandle<JSFunction>(clsObj)->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX); 1365 ASSERT_TRUE(!accessor.IsUndefinedOrNull()); 1366} 1367 1368HWTEST_F_L0(JSNApiTests, WeakRefSecondPassCallback) 1369{ 1370 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1371 LocalScope scope(vm_); 1372 Local<ObjectRef> object1 = ObjectRef::New(vm_); 1373 Global<ObjectRef> globalObject1(vm_, object1); 1374 globalObject1.SetWeak(); 1375 NativeReferenceHelper *temp = nullptr; 1376 { 1377 LocalScope scope1(vm_); 1378 Local<ObjectRef> object2 = ObjectRef::New(vm_); 1379 Global<ObjectRef> globalObject2(vm_, object2); 1380 NativeReferenceHelper *ref1 = new NativeReferenceHelper(vm_, globalObject2, WeakRefCallback); 1381 ref1->SetWeakCallback(); 1382 temp = ref1; 1383 } 1384 { 1385 LocalScope scope1(vm_); 1386 Local<ObjectRef> object3 = ObjectRef::New(vm_); 1387 Global<ObjectRef> globalObject3(vm_, object3); 1388 globalObject3.SetWeak(); 1389 } 1390 Local<ObjectRef> object4 = ObjectRef::New(vm_); 1391 Global<ObjectRef> globalObject4(vm_, object4); 1392 NativeReferenceHelper *ref2 = new NativeReferenceHelper(vm_, globalObject4, WeakRefCallback); 1393 ref2->SetWeakCallback(); 1394 vm_->CollectGarbage(TriggerGCType::OLD_GC); 1395 delete temp; 1396 delete ref2; 1397} 1398 1399/** 1400 * @tc.number: ffi_interface_api_027 1401 * @tc.name: TriggerGC_OLD_GC 1402 * @tc.desc: GC trigger, gcType is the trigger type 1403 * @tc.type: FUNC 1404 * @tc.require: parameter 1405 */ 1406HWTEST_F_L0(JSNApiTests, TriggerGC_OLD_GC) 1407{ 1408 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread()); 1409 vm_->SetEnableForceGC(false); 1410 auto globalEnv = vm_->GetGlobalEnv(); 1411 auto factory = vm_->GetFactory(); 1412 1413 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1"); 1414 ASSERT_EQ("1", origin->ToString(vm_)); 1415 1416 JSHandle<JSTaggedValue> jsFunc = globalEnv->GetArrayFunction(); 1417 JSHandle<JSObject> objVal1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc); 1418 JSHandle<JSObject> objVal2 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc); 1419 JSObject *newObj2 = *objVal2; 1420 JSTaggedValue canBeGcValue(newObj2); 1421 1422 uint32_t arrayLength = 2; 1423 JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(arrayLength); 1424 taggedArray->Set(thread_, 0, objVal1); 1425 taggedArray->Set(thread_, 1, canBeGcValue); 1426 EXPECT_EQ(taggedArray->GetIdx(objVal1.GetTaggedValue()), 0U); 1427 EXPECT_EQ(taggedArray->GetIdx(canBeGcValue), 1U); 1428 1429 // trigger gc 1430 JSNApi::TRIGGER_GC_TYPE gcType = JSNApi::TRIGGER_GC_TYPE::OLD_GC; 1431 JSNApi::TriggerGC(vm_, gcType); 1432 gcType = JSNApi::TRIGGER_GC_TYPE::SHARED_GC; 1433 JSNApi::TriggerGC(vm_, gcType); 1434 gcType = JSNApi::TRIGGER_GC_TYPE::SHARED_FULL_GC; 1435 JSNApi::TriggerGC(vm_, gcType); 1436 1437 EXPECT_EQ(taggedArray->GetIdx(objVal1.GetTaggedValue()), 0U); 1438 EXPECT_EQ(taggedArray->GetIdx(canBeGcValue), TaggedArray::MAX_ARRAY_INDEX); 1439 ASSERT_EQ("1", origin->ToString(vm_)); 1440 1441 vm_->SetEnableForceGC(true); 1442} 1443 1444HWTEST_F_L0(JSNApiTests, Hint_GC) 1445{ 1446 ecmascript::ThreadManagedScope managedScope(thread_); 1447 vm_->SetEnableForceGC(false); 1448 [[maybe_unused]] auto heap = const_cast<Heap *>(thread_->GetEcmaVM()->GetHeap()); 1449 1450#ifdef NDEBUG 1451 heap->CollectGarbage(TriggerGCType::OLD_GC); 1452 { 1453 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread_); 1454 for (int i = 0; i < 2049; i++) { 1455 [[maybe_unused]] JSHandle<TaggedArray> array = thread_->GetEcmaVM()->GetFactory()->NewTaggedArray( 1456 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1457 } 1458 } 1459 size_t beforeSize = heap->GetHeapObjectSize(); 1460#endif 1461 1462 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1"); 1463 ASSERT_EQ("1", origin->ToString(vm_)); 1464 1465 // trigger gc 1466 JSNApi::MemoryReduceDegree degree = JSNApi::MemoryReduceDegree::LOW; 1467 JSNApi::HintGC(vm_, degree, GCReason::HINT_GC); 1468 degree = JSNApi::MemoryReduceDegree::MIDDLE; 1469 JSNApi::HintGC(vm_, degree, GCReason::HINT_GC); 1470 degree = JSNApi::MemoryReduceDegree::HIGH; 1471 JSNApi::HintGC(vm_, degree, GCReason::HINT_GC); 1472 1473 ASSERT_EQ("1", origin->ToString(vm_)); 1474#ifdef NDEBUG 1475 size_t afterSize = heap->GetHeapObjectSize(); 1476 EXPECT_TRUE(afterSize < beforeSize); 1477#endif 1478 vm_->SetEnableForceGC(true); 1479} 1480 1481/* @tc.number: ffi_interface_api_028 1482 * @tc.name: addWorker_DeleteWorker 1483 * @tc.desc: 1484 * addWorker:Using a WorkerVm as a parameter to modify the workInfo of the current vm 1485 * DeleteWorker:Delete WorkerVm 1486 * @tc.type: FUNC 1487 * @tc.require: parameter 1488 */ 1489HWTEST_F_L0(JSNApiTests, addWorker_DeleteWorker) 1490{ 1491 std::thread t1([&]() { 1492 JSRuntimeOptions option; 1493 EcmaVM *workerVm = JSNApi::CreateEcmaVM(option); 1494 JSNApi::AddWorker(vm_, workerVm); 1495 bool hasDeleted = JSNApi::DeleteWorker(vm_, workerVm); 1496 JSNApi::DestroyJSVM(workerVm); 1497 EXPECT_TRUE(hasDeleted); 1498 }); 1499 { 1500 ThreadSuspensionScope suspensionScope(thread_); 1501 t1.join(); 1502 } 1503 1504 bool hasDeleted = JSNApi::DeleteWorker(vm_, nullptr); 1505 EXPECT_FALSE(hasDeleted); 1506} 1507 1508/** 1509 * @tc.number: ffi_interface_api_029 1510 * @tc.name: PrimitiveRef_GetValue 1511 * @tc.desc:Create an IntegerRef object with an initial value of 0 1512 * and test whether the GetValue method can correctly return the associated JSValueRef object. 1513 * @tc.type: FUNC 1514 * @tc.require: parameter 1515 */ 1516HWTEST_F_L0(JSNApiTests, PrimitiveRef_GetValue) 1517{ 1518 auto factory = vm_->GetFactory(); 1519 Local<IntegerRef> intValue = IntegerRef::New(vm_, 0); 1520 EXPECT_EQ(intValue->Value(), 0); 1521 1522 Local<JSValueRef> jsValue = intValue->GetValue(vm_); 1523 EXPECT_TRUE(*jsValue == nullptr); 1524 1525 JSHandle<JSTaggedValue> nullHandle(thread_, JSTaggedValue::Null()); 1526 JSHandle<JSHClass> jsClassHandle = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_PRIMITIVE_REF, nullHandle); 1527 JSHandle<JSTaggedValue> jsTaggedValue(factory->NewJSObjectWithInit(jsClassHandle)); 1528 Local<PrimitiveRef> jsValueRef = JSNApiHelper::ToLocal<JSPrimitiveRef>(jsTaggedValue); 1529 EXPECT_TRUE(*(jsValueRef->GetValue(vm_)) != nullptr); 1530} 1531 1532HWTEST_F_L0(JSNApiTests, BigIntRef_New_Uint64) 1533{ 1534 uint64_t maxUint64 = std::numeric_limits<uint64_t>::max(); 1535 Local<BigIntRef> maxBigintUint64 = BigIntRef::New(vm_, maxUint64); 1536 EXPECT_TRUE(maxBigintUint64->IsBigInt(vm_)); 1537 1538 JSHandle<BigInt> maxBigintUint64Val(thread_, JSNApiHelper::ToJSTaggedValue(*maxBigintUint64)); 1539 EXPECT_EQ(maxBigintUint64Val->GetDigit(0), static_cast<uint32_t>(maxUint64 & 0xffffffff)); 1540 EXPECT_EQ(maxBigintUint64Val->GetDigit(1), static_cast<uint32_t>((maxUint64 >> BigInt::DATEBITS) & 0xffffffff)); 1541 1542 uint64_t minUint64 = std::numeric_limits<uint64_t>::min(); 1543 Local<BigIntRef> minBigintUint64 = BigIntRef::New(vm_, minUint64); 1544 EXPECT_TRUE(minBigintUint64->IsBigInt(vm_)); 1545 1546 JSHandle<BigInt> minBigintUint64Val(thread_, JSNApiHelper::ToJSTaggedValue(*minBigintUint64)); 1547 EXPECT_EQ(minBigintUint64Val->GetDigit(0), static_cast<uint32_t>(minUint64 & 0xffffffff)); 1548 EXPECT_EQ(minBigintUint64Val->GetLength(), 1U); 1549} 1550 1551HWTEST_F_L0(JSNApiTests, BigIntRef_New_Int64) 1552{ 1553 int64_t maxInt64 = std::numeric_limits<int64_t>::max(); 1554 Local<BigIntRef> maxBigintInt64 = BigIntRef::New(vm_, maxInt64); 1555 EXPECT_TRUE(maxBigintInt64->IsBigInt(vm_)); 1556 1557 JSHandle<BigInt> maxBigintInt64Val(thread_, JSNApiHelper::ToJSTaggedValue(*maxBigintInt64)); 1558 EXPECT_EQ(maxBigintInt64Val->GetDigit(0), static_cast<uint32_t>(maxInt64 & 0xffffffff)); 1559 EXPECT_EQ(maxBigintInt64Val->GetDigit(1), static_cast<uint32_t>((maxInt64 >> BigInt::DATEBITS) & 0xffffffff)); 1560 1561 int64_t minInt64 = std::numeric_limits<int64_t>::min(); 1562 Local<BigIntRef> minBigintInt64 = BigIntRef::New(vm_, minInt64); 1563 EXPECT_TRUE(minBigintInt64->IsBigInt(vm_)); 1564 1565 JSHandle<BigInt> minBigintInt64Val(thread_, JSNApiHelper::ToJSTaggedValue(*minBigintInt64)); 1566 EXPECT_EQ(minBigintInt64Val->GetSign(), true); 1567 EXPECT_EQ(minBigintInt64Val->GetDigit(0), static_cast<uint32_t>((-minInt64) & 0xffffffff)); 1568 EXPECT_EQ(minBigintInt64Val->GetDigit(1), static_cast<uint32_t>(((-minInt64) >> BigInt::DATEBITS) & 0xffffffff)); 1569} 1570 1571/** 1572 * @tc.number: ffi_interface_api_030 1573 * @tc.name: BigIntRef_CreateBigWords_GetWordsArray_GetWordsArraySize 1574 * @tc.desc: 1575 * IsBigInt:Determine if it is bigint 1576 * @tc.type: FUNC 1577 * @tc.require: parameter 1578 */ 1579HWTEST_F_L0(JSNApiTests, BigIntRef_CreateBigWords_GetWordsArray_GetWordsArraySize) 1580{ 1581 bool sign = false; 1582 uint32_t size = 3; 1583 const uint32_t MULTIPLE = 2; 1584 const uint64_t words[3] = { 1585 std::numeric_limits<uint64_t>::min() - 1, 1586 std::numeric_limits<uint64_t>::min(), 1587 std::numeric_limits<uint64_t>::max(), 1588 }; 1589 Local<JSValueRef> bigWords = BigIntRef::CreateBigWords(vm_, sign, size, words); 1590 EXPECT_TRUE(bigWords->IsBigInt(vm_)); 1591 1592 Local<BigIntRef> bigWordsRef(bigWords); 1593 EXPECT_EQ(bigWordsRef->GetWordsArraySize(vm_), size); 1594 1595 JSHandle<BigInt> bigintUint64Val(thread_, JSNApiHelper::ToJSTaggedValue(*bigWords)); 1596 EXPECT_EQ(bigintUint64Val->GetSign(), false); 1597 EXPECT_EQ(bigintUint64Val->GetLength(), size * MULTIPLE); 1598 1599 bool resultSignBit = true; 1600 uint64_t *resultWords = new uint64_t[3](); // 3 : length of words array 1601 bigWordsRef->GetWordsArray(vm_, &resultSignBit, size, resultWords); 1602 EXPECT_EQ(resultSignBit, false); 1603 EXPECT_EQ(resultWords[0], words[0]); 1604 EXPECT_EQ(resultWords[1], words[1]); 1605 EXPECT_EQ(resultWords[2], words[2]); 1606 delete[] resultWords; 1607} 1608 1609/** 1610 * @tc.number: ffi_interface_api_031 1611 * @tc.name: DateRef_New_ToString_GetTime_BigIntRef_CreateBigWords_GetWordsArray 1612 * @tc.desc:The purpose of testing is to verify whether the DateRef method correctly converts time to Date type 1613 * and converts Date type to string type, while also verifying whether its operation to obtain time is correct. 1614 * Used to verify the success of creating a BigIntRef object and obtaining a 1615 * word array of large integer objects. 1616 * @tc.type: FUNC 1617 * @tc.require: parameter 1618 */ 1619HWTEST_F_L0(JSNApiTests, DateRef_New_ToString_GetTime) 1620{ 1621 double time = 1.1; 1622 Local<DateRef> data = DateRef::New(vm_, time); 1623 EXPECT_TRUE(data->IsDate(vm_)); 1624 1625 Local<StringRef> tostring = data->ToString(vm_); 1626 Local<JSValueRef> toValue(tostring); 1627 EXPECT_TRUE(tostring->IsString(vm_)); 1628 double dou = data->GetTime(vm_); 1629 EXPECT_EQ(dou, 1.1); 1630} 1631 1632HWTEST_F_L0(JSNApiTests, PromiseRef_Finally) 1633{ 1634 LocalScope scope(vm_); 1635 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 1636 1637 Local<PromiseRef> promise = capability->GetPromise(vm_); 1638 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback); 1639 Local<PromiseRef> catchPromise = promise->Finally(vm_, reject); 1640 ASSERT_TRUE(promise->IsPromise(vm_)); 1641 ASSERT_TRUE(catchPromise->IsPromise(vm_)); 1642 Local<PromiseRef> catchPromise1 = promise->Then(vm_, reject, reject); 1643 ASSERT_TRUE(catchPromise1->IsPromise(vm_)); 1644 Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback); 1645 ASSERT_TRUE(!callback.IsEmpty()); 1646 Local<PromiseRef> catchPromise2 = promise->Then(vm_, callback); 1647 ASSERT_TRUE(catchPromise2->IsPromise(vm_)); 1648} 1649 1650/* 1651 * @tc.number: ffi_interface_api_032 1652 * @tc.name: JSNApi_SerializeValue 1653 * @tc.desc: The main function of Undefined is to initialize some variables for subsequent testing, 1654 * testing the correctness and reliability of the JSNApi:: SerializeValue function, 1655 * and ensuring that it can serialize values correctly. 1656 * @tc.type: FUNC 1657 * @tc.require: parameter 1658 */ 1659HWTEST_F_L0(JSNApiTests, JSNApi_SerializeValue) 1660{ 1661 LocalScope scope(vm_); 1662 Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback); 1663 ASSERT_TRUE(!callback.IsEmpty()); 1664 std::vector<Local<JSValueRef>> arguments; 1665 arguments.emplace_back(JSValueRef::Undefined(vm_)); 1666 Local<JSValueRef> result = callback->Call(vm_, JSValueRef::Undefined(vm_), arguments.data(), arguments.size()); 1667 ASSERT_TRUE(result->IsArray(vm_)); 1668 Local<ArrayRef> array(result); 1669 ASSERT_EQ(static_cast<uint64_t>(array->Length(vm_)), arguments.size()); 1670 void *res = nullptr; 1671 res = JSNApi::SerializeValue(vm_, result, JSValueRef::Undefined(vm_), JSValueRef::Undefined(vm_), true); 1672 EXPECT_TRUE(res); 1673} 1674 1675/* 1676 * @tc.number: ffi_interface_api_033 1677 * @tc.name: JSNApi_SetHostPromiseRejectionTracker_Call 1678 * @tc.desc: Can the host Promise reject callback function of the JavaScript virtual machine be set correctly. 1679 * @ Using the functions of Uint8Array and verifying if its attribute values are correct. 1680 * @tc.type: FUNC 1681 * @tc.require: parameter 1682 */ 1683HWTEST_F_L0(JSNApiTests, JSNApi_SetHostPromiseRejectionTracker) 1684{ 1685 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf); 1686 // 设置 JavaScript 虚拟机的宿主 Promise 拒绝回调函数为 data 所指向的函数。 1687 JSNApi::SetHostPromiseRejectionTracker(vm_, data, data); 1688 // 首先获取GetJS虚拟机中的当前线程->GetCurrentEcmaContext获取当前上下文->从上下文中获取Promise拒绝回调函数 1689 PromiseRejectCallback res = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPromiseRejectCallback(); 1690 // 检查回调函数的地址是否等于我们之前设置的 data 的地址 1691 ASSERT_EQ(res, reinterpret_cast<ecmascript::PromiseRejectCallback>(data)); 1692} 1693 1694HWTEST_F_L0(JSNApiTests, JSNApi_SetNativePtrGetter_SetHostEnqueueJob) 1695{ 1696 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf); 1697 JSNApi::SetNativePtrGetter(vm_, cb); 1698 NativePtrGetter res = vm_->GetNativePtrGetter(); 1699 ASSERT_EQ(res, reinterpret_cast<ecmascript::NativePtrGetter>(cb)); 1700} 1701 1702HWTEST_F_L0(JSNApiTests, NumberRef_New) 1703{ 1704 uint32_t input = 32; 1705 int64_t input1 = 1; 1706 Local<NumberRef> res = NumberRef::New(vm_, input); 1707 Local<NumberRef> res1 = NumberRef::New(vm_, input1); 1708 ASSERT_TRUE(res->IsNumber()); 1709 ASSERT_TRUE(res1->IsNumber()); 1710} 1711 1712/** 1713 * @tc.number: ffi_interface_api_034 1714 * @tc.name: ObjectRef_GetOwnEnumerablePropertyNames 1715 * @tc.desc:Use the GetOwnEnumerablePropertyNames method to obtain all enumerable property names of the object 1716 * and return an ArrayRef object. 1717 * @tc.type: FUNC 1718 * @tc.require: parameter 1719 */ 1720HWTEST_F_L0(JSNApiTests, ObjectRef_GetOwnEnumerablePropertyNames) 1721{ 1722 LocalScope scope(vm_); 1723 Local<ObjectRef> object = ObjectRef::New(vm_); 1724 Local<ArrayRef> res = object->GetOwnEnumerablePropertyNames(vm_); 1725 ASSERT_TRUE(res->IsArray(vm_)); 1726} 1727 1728/** 1729 * @tc.number: ffi_interface_api_035 1730 * @tc.name: ObjectRef_SetNativePointerFieldCount_GetNativePointerFieldCount 1731 * @tc.desc: 1732 * SetNativePointerFieldCount:Set the count value of the local pointer field to count 1733 * GetNativePointerField:Get native pointer object 1734 * SetNativePointerField:Set native pointer properties, including pointers, callback methods, 1735 * data, and number of bindings 1736 * @tc.type: FUNC 1737 * @tc.require: parameter 1738 */ 1739HWTEST_F_L0(JSNApiTests, ObjectRef_SetNativePointerFieldCount_GetNativePointerFieldCount) 1740{ 1741 LocalScope scope(vm_); 1742 Local<ObjectRef> object = ObjectRef::New(vm_); 1743 int32_t input = 34; 1744 object->SetNativePointerFieldCount(vm_, input); 1745 int32_t res = object->GetNativePointerFieldCount(vm_); 1746 ASSERT_EQ(res, input); 1747 NativePointerCallback callBack = nullptr; 1748 void *vp1 = static_cast<void *>(new std::string("test")); 1749 void *vp2 = static_cast<void *>(new std::string("test")); 1750 std::string *sp1 = static_cast<std::string *>(vp1); 1751 object->SetNativePointerField(vm_, 33, vp1, callBack, vp2); 1752 void *res1 = object->GetNativePointerField(vm_, 33); 1753 std::string *sp2 = static_cast<std::string *>(res1); 1754 ASSERT_EQ(sp1, sp2); 1755} 1756 1757/** 1758 * @tc.number: ffi_interface_api_036 1759 * @tc.name: FunctionRef_GetFunctionPrototype_SetName_GetName 1760 * @tc.desc:Mainly used to verify the correctness of methods such as creating, obtaining prototypes, 1761 * setting names, and obtaining FunctionRef objects. 1762 * @tc.type: FUNC 1763 * @tc.require: parameter 1764 */ 1765HWTEST_F_L0(JSNApiTests, FunctionRef_GetFunctionPrototype_SetName_GetName) 1766{ 1767 LocalScope scope(vm_); 1768 NativePointerCallback deleter = nullptr; 1769 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf); 1770 bool callNative = true; 1771 size_t nativeBindingsize = 15; 1772 Local<FunctionRef> res = 1773 FunctionRef::NewClassFunction(vm_, FunctionCallback, deleter, cb, callNative, nativeBindingsize); 1774 ASSERT_TRUE(res->IsFunction(vm_)); 1775 Local<JSValueRef> res1 = res->GetFunctionPrototype(vm_); 1776 ASSERT_TRUE(res->IsFunction(vm_)); 1777 ASSERT_TRUE(!res1->IsArray(vm_)); 1778 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1"); 1779 res->SetName(vm_, origin); 1780 Local<StringRef> s = res->GetName(vm_); 1781 std::string str = s->ToString(vm_); 1782 ASSERT_EQ("1", str); 1783} 1784 1785HWTEST_F_L0(JSNApiTests, JSNApi_SetAssetPath_GetAssetPath) 1786{ 1787 LocalScope scope(vm_); 1788 std::string str = "/data/storage/el1/bundle/moduleName/ets/modules.abc"; 1789 JSNApi::SetAssetPath(vm_, str); 1790 std::string res = JSNApi::GetAssetPath(vm_); 1791 ASSERT_EQ(str, res); 1792 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf); 1793 JSNApi::SetLoop(vm_, data); 1794 void *res1 = vm_->GetLoop(); 1795 ASSERT_EQ(res1, data); 1796} 1797 1798/** 1799 * @tc.number: ffi_interface_api_037 1800 * @tc.name: SetAssetPath 1801 * @tc.desc:The resource file path used to verify the success of the setup program. 1802 * @tc.type: FUNC 1803 * @tc.require: parameter 1804 */ 1805 1806HWTEST_F_L0(JSNApiTests, JSValueRef_ToNativePointer) 1807{ 1808 LocalScope scope(vm_); 1809 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3"); 1810 Local<JSValueRef> toValue(toString); 1811 ASSERT_EQ(toString->ToNumber(vm_)->Value(), -123.3); // -123 : test case of input 1812 ASSERT_EQ(toString->ToBoolean(vm_)->Value(), true); 1813 ASSERT_EQ(toValue->ToString(vm_)->ToString(vm_), "-123.3"); 1814 ASSERT_TRUE(toValue->ToObject(vm_)->IsObject(vm_)); 1815 Local<NativePointerRef> res = toValue->ToNativePointer(vm_); 1816 ASSERT_TRUE(res->IsString(vm_)); 1817} 1818 1819HWTEST_F_L0(JSNApiTests, GeneratorObjectRef_IsGenerator) 1820{ 1821 ObjectFactory *factory = vm_->GetFactory(); 1822 auto env = vm_->GetGlobalEnv(); 1823 1824 JSHandle<JSTaggedValue> genFunc = env->GetGeneratorFunctionFunction(); 1825 JSHandle<JSGeneratorObject> genObjHandleVal = factory->NewJSGeneratorObject(genFunc); 1826 1827 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass()); 1828 JSHandle<JSFunction> generatorFunc = JSHandle<JSFunction>::Cast(factory->NewJSObject(hclass)); 1829 JSFunction::InitializeJSFunction(thread_, generatorFunc, FunctionKind::GENERATOR_FUNCTION); 1830 1831 JSHandle<GeneratorContext> generatorContext = factory->NewGeneratorContext(); 1832 generatorContext->SetMethod(thread_, generatorFunc.GetTaggedValue()); 1833 1834 JSHandle<JSTaggedValue> generatorContextVal = JSHandle<JSTaggedValue>::Cast(generatorContext); 1835 genObjHandleVal->SetGeneratorContext(thread_, generatorContextVal.GetTaggedValue()); 1836 1837 JSHandle<JSTaggedValue> genObjTagHandleVal = JSHandle<JSTaggedValue>::Cast(genObjHandleVal); 1838 Local<GeneratorObjectRef> genObjectRef = JSNApiHelper::ToLocal<GeneratorObjectRef>(genObjTagHandleVal); 1839 Local<JSValueRef> res = genObjectRef->GetGeneratorFunction(vm_); 1840 ASSERT_TRUE(res->IsGeneratorFunction(vm_)); 1841} 1842 1843/** 1844 * @tc.number: ffi_interface_api_038 1845 * @tc.name: BigIntToInt64 1846 * @tc.desc:Is the method of converting BigInt objects to 64 bit signed integers correct, and is it able to 1847 * handle lossless conversions correctly. 1848 * @tc.type: FUNC 1849 * @tc.require: parameter 1850 */ 1851HWTEST_F_L0(JSNApiTests, BigIntToInt64) 1852{ 1853 LocalScope scope(vm_); 1854 uint64_t maxUint64 = std::numeric_limits<uint64_t>::max(); 1855 Local<BigIntRef> maxBigintUint64 = BigIntRef::New(vm_, maxUint64); 1856 EXPECT_TRUE(maxBigintUint64->IsBigInt(vm_)); 1857 int64_t num = -11; 1858 int64_t num1 = num; 1859 bool lossless = true; 1860 maxBigintUint64->BigIntToInt64(vm_, &num, &lossless); 1861 EXPECT_TRUE(num != num1); 1862} 1863 1864/** 1865 * @tc.number: ffi_interface_api_039 1866 * @tc.name: BigIntToUint64 1867 * @tc.desc:Is the method for converting BigInt objects to 64 bit unsigned integers correct and can lossless 1868 * conversions be handled correctly. 1869 * @tc.type: FUNC 1870 * @tc.require: parameter 1871 */ 1872HWTEST_F_L0(JSNApiTests, BigIntToUint64) 1873{ 1874 LocalScope scope(vm_); 1875 uint64_t maxUint64 = std::numeric_limits<uint64_t>::max(); 1876 Local<BigIntRef> maxBigintUint64 = BigIntRef::New(vm_, maxUint64); 1877 EXPECT_TRUE(maxBigintUint64->IsBigInt(vm_)); 1878 uint64_t num = -11; 1879 uint64_t num1 = num; 1880 bool lossless = true; 1881 maxBigintUint64->BigIntToUint64(vm_, &num, &lossless); 1882 EXPECT_TRUE(num != num1); 1883} 1884 1885HWTEST_F_L0(JSNApiTests, BooleanRef_New) 1886{ 1887 LocalScope scope(vm_); 1888 bool input = true; 1889 Local<BooleanRef> res = BooleanRef::New(vm_, input); 1890 EXPECT_TRUE(res->IsBoolean()); 1891 EXPECT_TRUE(res->BooleaValue(vm_)); 1892} 1893 1894/** 1895 * @tc.number: ffi_interface_api_040 1896 * @tc.name: NewFromUnsigned 1897 * @tc.desc:Verify that the NewFromUnsigned method of IntegerRef can correctly create an IntegerRef object 1898 * representing unsigned integers, and that the value of the object is correct. 1899 * Value () method to obtain the value of this object, and then assert that this value is equal to 1900 * the input unsigned integer 1. 1901 * @tc.type: FUNC 1902 * @tc.require: parameter 1903 */ 1904HWTEST_F_L0(JSNApiTests, NewFromUnsigned) 1905{ 1906 LocalScope scope(vm_); 1907 unsigned int input = 1; 1908 [[maybe_unused]] Local<IntegerRef> res = IntegerRef::NewFromUnsigned(vm_, input); 1909 EXPECT_TRUE(res->IntegerValue(vm_) == 1); 1910 EXPECT_TRUE(res->Value() == 1); 1911} 1912 1913HWTEST_F_L0(JSNApiTests, SetBundleName_GetBundleName) 1914{ 1915 LocalScope scope(vm_); 1916 std::string str = "11"; 1917 JSNApi::SetBundleName(vm_, str); 1918 std::string res = JSNApi::GetBundleName(vm_); 1919 ASSERT_EQ(str, res); 1920} 1921 1922HWTEST_F_L0(JSNApiTests, SetModuleName_GetModuleName) 1923{ 1924 LocalScope scope(vm_); 1925 std::string str = "11"; 1926 JSNApi::SetModuleName(vm_, str); 1927 std::string res = JSNApi::GetModuleName(vm_); 1928 ASSERT_EQ(str, res); 1929} 1930 1931/** 1932 * @tc.number: ffi_interface_api_041 1933 * @tc.name: IsBundle 1934 * @tc.desc: Determine if it is a type of Bundle 1935 * @tc.type: FUNC 1936 * @tc.require: parameter 1937 */ 1938HWTEST_F_L0(JSNApiTests, IsBundle) 1939{ 1940 LocalScope scope(vm_); 1941 bool res = JSNApi::IsBundle(vm_); 1942 ASSERT_EQ(res, true); 1943} 1944 1945/** 1946 * @tc.number: ffi_interface_api_042 1947 * @tc.name: ObjectRef_Delete 1948 * @tc.desc:MapRef_GetSize_GetTotalElements_Get_GetKey_GetValue_New_Set 1949 * @tc.type: FUNC 1950 * @tc.require: parameter 1951 */ 1952HWTEST_F_L0(JSNApiTests, MapRef_GetSize_GetTotalElements_Get_GetKey_GetValue_New_Set) 1953{ 1954 LocalScope scope(vm_); 1955 Local<MapRef> map = MapRef::New(vm_); 1956 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 1957 Local<JSValueRef> value = StringRef::NewFromUtf8(vm_, "TestValue"); 1958 map->Set(vm_, key, value); 1959 Local<JSValueRef> res = map->Get(vm_, key); 1960 ASSERT_EQ(res->ToString(vm_)->ToString(vm_), value->ToString(vm_)->ToString(vm_)); 1961 int32_t num = map->GetSize(vm_); 1962 int32_t num1 = map->GetTotalElements(vm_); 1963 ASSERT_EQ(num, 1); 1964 ASSERT_EQ(num1, 1); 1965 Local<JSValueRef> res1 = map->GetKey(vm_, 0); 1966 ASSERT_EQ(res1->ToString(vm_)->ToString(vm_), key->ToString(vm_)->ToString(vm_)); 1967 Local<JSValueRef> res2 = map->GetValue(vm_, 0); 1968 ASSERT_EQ(res2->ToString(vm_)->ToString(vm_), value->ToString(vm_)->ToString(vm_)); 1969} 1970 1971HWTEST_F_L0(JSNApiTests, GetSourceCode) 1972{ 1973 LocalScope scope(vm_); 1974 Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback); 1975 bool res = callback->IsNative(vm_); 1976 EXPECT_TRUE(res); 1977} 1978 1979/** 1980 * @tc.number: ffi_interface_api_043 1981 * @tc.name: ObjectRef_Delete_GetSourceCode 1982 * @tc.desc:Verify that the Delete method of the Object Ref object correctly deletes a property and that 1983 * the object no longer contains the property. 1984 * Using the functions of getsourcecode and verifying if its attribute values are correct. 1985 * @tc.type: FUNC 1986 * @tc.require: parameter 1987 */ 1988HWTEST_F_L0(JSNApiTests, ObjectRef_Delete) 1989{ 1990 LocalScope scope(vm_); 1991 Local<ObjectRef> object = ObjectRef::New(vm_); 1992 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey"); 1993 Local<JSValueRef> value = ObjectRef::New(vm_); 1994 PropertyAttribute attribute(value, true, true, true); 1995 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute)); 1996 ASSERT_TRUE(object->Delete(vm_, key)); 1997 ASSERT_FALSE(object->Has(vm_, key)); 1998} 1999 2000 2001/** 2002 * @tc.number: ffi_interface_api_044 2003 * @tc.name: Has 2004 * @tc.desc: Used to verify whether a given check object has the specified properties. 2005 * @tc.type: FUNC 2006 * @tc.require: parameter 2007 */ 2008HWTEST_F_L0(JSNApiTests, ObjectRef_Set1) 2009{ 2010 LocalScope scope(vm_); 2011 Local<ObjectRef> object = ObjectRef::New(vm_); 2012 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3"); 2013 Local<JSValueRef> toValue(toString); 2014 bool res = object->Set(vm_, 12, toValue); 2015 ASSERT_TRUE(res); 2016 Local<JSValueRef> res1 = object->Get(vm_, 12); 2017 ASSERT_EQ(res1->ToString(vm_)->ToString(vm_), toValue->ToString(vm_)->ToString(vm_)); 2018} 2019 2020HWTEST_F_L0(JSNApiTests, NativePointerRef_New) 2021{ 2022 LocalScope scope(vm_); 2023 NativePointerCallback callBack = nullptr; 2024 void *vp1 = static_cast<void *>(new std::string("test")); 2025 void *vp2 = static_cast<void *>(new std::string("test")); 2026 Local<NativePointerRef> res = NativePointerRef::New(vm_, vp1, callBack, vp2, 0); 2027 ASSERT_EQ(res->Value(), vp1); 2028} 2029 2030 2031/** 2032 * @tc.number: ffi_interface_api_045 2033 * @tc.name: PromiseRejectInfo_GetData 2034 * @tc.desc:Construct a BufferRef function to determine whether it is a ObjectRef_Has_Delete 2035 * @tc.type: FUNC 2036 * @tc.require: parameter 2037 */ 2038HWTEST_F_L0(JSNApiTests, ObjectRef_Has_Delete) 2039{ 2040 LocalScope scope(vm_); 2041 Local<ObjectRef> object = ObjectRef::New(vm_); 2042 uint32_t num = 10; 2043 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3"); 2044 Local<JSValueRef> toValue(toString); 2045 bool res = object->Set(vm_, num, toValue); 2046 ASSERT_TRUE(res); 2047 bool res1 = object->Has(vm_, num); 2048 ASSERT_TRUE(res1); 2049 bool res2 = object->Delete(vm_, num); 2050 ASSERT_TRUE(res2); 2051 bool res3 = object->Has(vm_, num); 2052 ASSERT_FALSE(res3); 2053} 2054 2055/** 2056 * @tc.number: ffi_interface_api_046 2057 * @tc.name: PromiseRejectInfo_GetData 2058 * @tc.desc:Mainly tested whether the GetData method of the PromiseRejectInfo object can correctly return 2059 * the incoming data, and whether the GetPromise and GetReason methods can correctly return Promise and the 2060 * reason for rejection. 2061 * @tc.type: FUNC 2062 * @tc.require: parameter 2063 */ 2064HWTEST_F_L0(JSNApiTests, PromiseRejectInfo_GetData) 2065{ 2066 LocalScope scope(vm_); 2067 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3"); 2068 Local<JSValueRef> promise(toString); 2069 Local<StringRef> toString1 = StringRef::NewFromUtf8(vm_, "123.3"); 2070 Local<JSValueRef> reason(toString1); 2071 void *data = static_cast<void *>(new std::string("test")); 2072 // 创建一个PromiseRejectInfo对象,并传入被拒绝的Promise,拒绝的原因,拒绝事件类型以及自定义数据 2073 PromiseRejectInfo promisereject(promise, reason, PromiseRejectInfo::PROMISE_REJECTION_EVENT::REJECT, data); 2074 // 从上一步创建的PromiseRejectInfo对象中获取被拒绝的Promise,并在下面断言被拒绝的Promise与原始Promise相同 2075 Local<JSValueRef> promise_res = promisereject.GetPromise(); 2076 // 获取拒绝的原因,并在下面断言拒绝原因与原始拒绝原因相同 2077 Local<JSValueRef> reason_res = promisereject.GetReason(); 2078 ASSERT_EQ(promise_res->ToString(vm_)->ToString(vm_), promise->ToString(vm_)->ToString(vm_)); 2079 ASSERT_EQ(reason_res->ToString(vm_)->ToString(vm_), reason->ToString(vm_)->ToString(vm_)); 2080 // 获取自定义数据,并在下面断言自定义数据与传入的数据相同 2081 void *dataRes = promisereject.GetData(); 2082 ASSERT_EQ(dataRes, data); 2083} 2084 2085/** 2086 * @tc.number: ffi_interface_api_047 2087 * @tc.name: FunctionCallScope 2088 * @tc.desc:Create and use the function call scope function, and verify whether the depth of function calls is 2089 * correct when entering and exiting the scope. 2090 * @tc.type: FUNC 2091 * @tc.require: parameter 2092 */ 2093HWTEST_F_L0(JSNApiTests, FunctionCallScope) 2094{ 2095 { 2096 FunctionCallScope callScope(vm_); 2097 ASSERT_FALSE(vm_->IsTopLevelCallDepth()); 2098 } 2099 ASSERT_TRUE(vm_->IsTopLevelCallDepth()); 2100} 2101 2102HWTEST_F_L0(JSNApiTests, AotTrigger) 2103{ 2104 std::string bundle; 2105 std::string module; 2106 int32_t trigger = -1; 2107 JSNApi::SetRequestAotCallback(vm_, 2108 [&](const std::string &bundleName, const std::string &moduleName, int32_t triggerMode) -> bool { 2109 bundle = bundleName; 2110 module = moduleName; 2111 trigger = triggerMode; 2112 return 100; 2113 }); 2114 ASSERT_FALSE(ecmascript::pgo::PGOProfilerManager::GetInstance()->RequestAot("com.test.test", "requestAot", 2115 RequestAotMode::RE_COMPILE_ON_IDLE)); 2116 ASSERT_EQ(bundle, "com.test.test"); 2117 ASSERT_EQ(module, "requestAot"); 2118 ASSERT_EQ(trigger, 0); 2119} 2120 2121HWTEST_F_L0(JSNApiTests, JSNApiInternalsTest) 2122{ 2123#define CHECK_VALUE(VAL) ASSERT_EQ(JSValueRefInternals::VAL, JSTaggedValue::VAL) 2124 CHECK_VALUE(BIT_PER_BYTE); 2125 CHECK_VALUE(TAG_BITS_SIZE); 2126 CHECK_VALUE(TAG_BITS_SHIFT); 2127 CHECK_VALUE(TAG_MARK); 2128 CHECK_VALUE(TAG_INT); 2129 CHECK_VALUE(TAG_INT32_INC_MAX); 2130 CHECK_VALUE(TAG_INT32_DEC_MIN); 2131 CHECK_VALUE(TAG_OBJECT); 2132 CHECK_VALUE(TAG_WEAK); 2133 CHECK_VALUE(TAG_NULL); 2134 CHECK_VALUE(TAG_SPECIAL); 2135 CHECK_VALUE(TAG_BOOLEAN); 2136 CHECK_VALUE(TAG_EXCEPTION); 2137 CHECK_VALUE(TAG_OPTIMIZED_OUT); 2138 CHECK_VALUE(TAG_SPECIAL_MASK); 2139 CHECK_VALUE(TAG_BOOLEAN_MASK); 2140 CHECK_VALUE(TAG_HEAPOBJECT_MASK); 2141 CHECK_VALUE(TAG_WEAK_MASK); 2142 CHECK_VALUE(VALUE_HOLE); 2143 CHECK_VALUE(VALUE_NULL); 2144 CHECK_VALUE(VALUE_FALSE); 2145 CHECK_VALUE(VALUE_TRUE); 2146 CHECK_VALUE(VALUE_UNDEFINED); 2147 CHECK_VALUE(VALUE_EXCEPTION); 2148 CHECK_VALUE(VALUE_ZERO); 2149 CHECK_VALUE(VALUE_OPTIMIZED_OUT); 2150 CHECK_VALUE(INT_SIGN_BIT_OFFSET); 2151 CHECK_VALUE(DOUBLE_ENCODE_OFFSET_BIT); 2152 CHECK_VALUE(DOUBLE_ENCODE_OFFSET); 2153 CHECK_VALUE(VALUE_POSITIVE_ZERO); 2154 CHECK_VALUE(VALUE_NEGATIVE_ZERO); 2155#undef CHECK_VALUE 2156} 2157 2158HWTEST_F_L0(JSNApiTests, JSNApiInternalsTestNumberRef) 2159{ 2160 // double 2161 TestNumberRef(0., JSTaggedValue::DOUBLE_ENCODE_OFFSET); 2162 TestNumberRef(NAN, base::bit_cast<TaggedType>(ecmascript::base::NAN_VALUE) + JSTaggedValue::DOUBLE_ENCODE_OFFSET); 2163 2164 // int32_t 2165 TestNumberRef(static_cast<int32_t>(0), JSTaggedValue::TAG_INT); 2166 TestNumberRef(INT32_MIN, static_cast<JSTaggedType>(INT32_MIN) | JSTaggedValue::TAG_INT); 2167 TestNumberRef(INT32_MAX, static_cast<JSTaggedType>(INT32_MAX) | JSTaggedValue::TAG_INT); 2168 2169 // uint32_t 2170 TestNumberRef(static_cast<uint32_t>(0), JSTaggedValue::TAG_INT); 2171 TestNumberRef(static_cast<uint32_t>(INT32_MAX), static_cast<uint32_t>(INT32_MAX) | JSTaggedValue::TAG_INT); 2172 auto val = static_cast<uint32_t>(INT32_MAX + 1UL); 2173 TestNumberRef(val, ConvertDouble(static_cast<double>(val))); 2174 TestNumberRef(UINT32_MAX, ConvertDouble(static_cast<double>(UINT32_MAX))); 2175 2176 // int64_t 2177 TestNumberRef(static_cast<int64_t>(INT32_MIN), static_cast<JSTaggedType>(INT32_MIN) | JSTaggedValue::TAG_INT); 2178 TestNumberRef(static_cast<int64_t>(INT32_MAX), static_cast<JSTaggedType>(INT32_MAX) | JSTaggedValue::TAG_INT); 2179 TestNumberRef(INT64_MIN, ConvertDouble(static_cast<double>(INT64_MIN))); 2180 TestNumberRef(INT64_MAX, ConvertDouble(static_cast<double>(INT64_MAX))); 2181} 2182 2183HWTEST_F_L0(JSNApiTests, JSNApiInternalsTestBooleanRef) 2184{ 2185 LocalScope scope(vm_); 2186 bool input = true; 2187 Local<BooleanRef> res = BooleanRef::New(vm_, input); 2188 EXPECT_TRUE(res->IsBoolean()); 2189 EXPECT_TRUE(res->BooleaValue(vm_)); 2190 ASSERT_EQ(JSNApiHelper::ToJSTaggedValue(*res).GetRawData(), JSTaggedValue::VALUE_TRUE); 2191 2192 input = false; 2193 res = BooleanRef::New(vm_, input); 2194 EXPECT_TRUE(res->IsBoolean()); 2195 EXPECT_FALSE(res->BooleaValue(vm_)); 2196 ASSERT_EQ(JSNApiHelper::ToJSTaggedValue(*res).GetRawData(), JSTaggedValue::VALUE_FALSE); 2197} 2198 2199HWTEST_F_L0(JSNApiTests, JSNApiInternalsTestNullUndefined) 2200{ 2201 LocalScope scope(vm_); 2202 Local<JSValueRef> null = JSValueRef::Null(vm_); 2203 ASSERT_TRUE(null->IsNull()); 2204 ASSERT_EQ(JSNApiHelper::ToJSTaggedValue(*null).GetRawData(), JSTaggedValue::VALUE_NULL); 2205 2206 Local<JSValueRef> undefined = JSValueRef::Undefined(vm_); 2207 ASSERT_TRUE(undefined->IsUndefined()); 2208 ASSERT_EQ(JSNApiHelper::ToJSTaggedValue(*undefined).GetRawData(), JSTaggedValue::VALUE_UNDEFINED); 2209} 2210 2211/** 2212 * @tc.number: ffi_interface_api_048 2213 * @tc.name: FunctionRef_New_GetFunctionPrototype 2214 * @tc.desc:The Inheritance Characteristics of Function References and the Function of Obtaining Function Headers 2215 * @tc.type: FUNC 2216 * @tc.require: parameter 2217 */ 2218HWTEST_F_L0(JSNApiTests, FunctionRef_New_GetFunctionPrototype) 2219{ 2220 LocalScope scope(vm_); 2221 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 2222 JSHandle<JSTaggedValue> set = env->GetBuiltinsSetFunction(); 2223 Local<FunctionRef> setLocal = JSNApiHelper::ToLocal<FunctionRef>(set); 2224 JSHandle<JSTaggedValue> map = env->GetBuiltinsMapFunction(); 2225 Local<FunctionRef> mapLocal = JSNApiHelper::ToLocal<FunctionRef>(map); 2226 JSHandle<JSTaggedValue> setPrototype(thread_, JSHandle<JSFunction>::Cast(set)->GetFunctionPrototype()); 2227 JSHandle<JSTaggedValue> mapPrototype(thread_, JSHandle<JSFunction>::Cast(map)->GetFunctionPrototype()); 2228 JSHandle<JSTaggedValue> mapPrototypeProto(thread_, JSTaggedValue::GetPrototype(thread_, mapPrototype)); 2229 bool same = JSTaggedValue::SameValue(setPrototype, mapPrototypeProto); 2230 ASSERT_FALSE(same); 2231 mapLocal->Inherit(vm_, setLocal); 2232 JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(mapLocal); 2233 JSHandle<JSTaggedValue> sonPrototype(thread_, JSHandle<JSFunction>::Cast(sonHandle)->GetFunctionPrototype()); 2234 JSHandle<JSTaggedValue> sonPrototypeProto(thread_, JSTaggedValue::GetPrototype(thread_, sonPrototype)); 2235 bool same2 = JSTaggedValue::SameValue(setPrototype, sonPrototypeProto); 2236 ASSERT_TRUE(same2); 2237 Local<FunctionRef> son1 = FunctionRef::New(vm_, FunctionCallback, nullptr); 2238 son1->Inherit(vm_, mapLocal); 2239 JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(son1)); 2240 ASSERT_TRUE(son1Handle->HasFunctionPrototype()); 2241} 2242 2243/* 2244 * @tc.number: ffi_interface_api_049 2245 * @tc.name: PrintExceptionInfo 2246 * @tc.desc: Obtain and print abnormal information correctly. 2247 * @tc.type: FUNC 2248 * @tc.require: parameter 2249 */ 2250HWTEST_F_L0(JSNApiTests, PrintExceptionInfo) 2251{ 2252 LocalScope scope(vm_); 2253 std::thread t1([&](){ 2254 RuntimeOption option; 2255 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR); 2256 auto *vm = JSNApi::CreateJSVM(option); 2257 ASSERT_TRUE(vm != nullptr) << "Cannot create Runtime"; 2258 JSNApi::PrintExceptionInfo(vm); 2259 JSNApi::DestroyJSVM(vm); 2260 }); 2261 { 2262 ThreadSuspensionScope suspensionScope(thread_); 2263 t1.join(); 2264 } 2265} 2266 2267/* 2268 * @tc.number: ffi_interface_api_050 2269 * @tc.name: IsNull 2270 * @tc.desc: Verify that localnull correctly represents a null value, ensuring that the JavaScript virtual machine 2271 * can handle null values correctly. 2272 * @tc.type: FUNC 2273 * @tc.require: parameter 2274 */ 2275HWTEST_F_L0(JSNApiTests, IsNull) 2276{ 2277 LocalScope scope(vm_); 2278 Local<JSValueRef> localNull = JSValueRef::Null(vm_); 2279 ASSERT_TRUE(localNull->IsNull()); 2280} 2281 2282/* 2283 * @tc.number: ffi_interface_api_051 2284 * @tc.name: IsNativePointer 2285 * @tc.desc: Verify that a NativePointerRef object created with a local pointer is correctly 2286 * recognized as a local pointer. 2287 * @tc.type: FUNC 2288 * @tc.require: parameter 2289 */ 2290HWTEST_F_L0(JSNApiTests, IsNativePointer) 2291{ 2292 LocalScope scope(vm_); 2293 NativePointerCallback callBack = nullptr; 2294 void *vp1 = static_cast<void *>(new std::string("test")); 2295 void *vp2 = static_cast<void *>(new std::string("test")); 2296 Local<NativePointerRef> res = NativePointerRef::New(vm_, vp1, callBack, vp2, 0); 2297 ASSERT_TRUE(res->IsNativePointer(vm_)); 2298} 2299 2300/* 2301 * @tc.number: ffi_interface_api_052 2302 * @tc.name: ToType_ToBoolean_ToString_ToObject 2303 * @tc.desc: Verify whether the ToType method of the JavaScript virtual machine can correctly convert string types to 2304 * the corresponding JavaScript data types. 2305 * Among them, there is the result of checking the string "-1.3" when it is converted to a Boolean value. 2306 * Check if the string wrapped in JSValueRef yields a result of "-1.3" when converted to a string. 2307 * Check if the string wrapped in JSValueRef actually becomes an object when converted to an object. 2308 * @tc.type: FUNC 2309 * @tc.require: parameter 2310 */ 2311HWTEST_F_L0(JSNApiTests, ToType_ToBoolean_ToString_ToObject) 2312{ 2313 LocalScope scope(vm_); 2314 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-1.3"); 2315 Local<JSValueRef> toValue(toString); 2316 2317 ASSERT_EQ(toString->ToNumber(vm_)->Value(), -1.3); 2318 ASSERT_EQ(toString->ToBoolean(vm_)->Value(), true); 2319 ASSERT_EQ(toValue->ToString(vm_)->ToString(vm_), "-1.3"); 2320 ASSERT_TRUE(toValue->ToObject(vm_)->IsObject(vm_)); 2321} 2322 2323/** 2324 * @tc.number: ffi_interface_api_053 2325 * @tc.name: IsTypedArray 2326 * @tc.desc:Verify that the TypedArray method correctly created a Uint32Array containing the specified 2327 * offset and length, and verify that its property values match expectations. 2328 * @tc.type: FUNC 2329 * @tc.require: parameter 2330 */ 2331HWTEST_F_L0(JSNApiTests, IsTypedArray) 2332{ 2333 LocalScope scope(vm_); 2334 std::string test = "abc"; 2335 char buffer[4]; 2336 memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); 2337 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str()); 2338 EXPECT_EQ(testString->WriteUtf8(vm_, buffer, 4), 4); 2339 // testString 是一个字符串,而不是类型化数组 2340 ASSERT_FALSE(testString->IsTypedArray(vm_)); 2341 const int32_t length = 30; 2342 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length); 2343 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_)); 2344 Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, 4, 6); 2345 // 是否是类型化数组 2346 ASSERT_TRUE(typedArray->IsTypedArray(vm_)); 2347 ASSERT_FALSE(typedArray->IsUndefined()); 2348 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_), arrayBuffer->GetBuffer(vm_)); 2349} 2350 2351HWTEST_F_L0(JSNApiTests, GetOriginalSource) 2352{ 2353 LocalScope scope(vm_); 2354 JSThread *thread = vm_->GetJSThread(); 2355 ObjectFactory *factory = vm_->GetFactory(); 2356 auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 2357 JSHandle<JSTaggedValue> regExpFunc = globalEnv->GetRegExpFunction(); 2358 JSHandle<JSRegExp> jSRegExp = 2359 JSHandle<JSRegExp>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(regExpFunc), regExpFunc)); 2360 jSRegExp->SetOriginalSource(thread, JSTaggedValue::Undefined()); 2361 Local<RegExpRef> object = JSNApiHelper::ToLocal<RegExpRef>(JSHandle<JSTaggedValue>::Cast(jSRegExp)); 2362 ASSERT_EQ(object->GetOriginalSource(vm_)->ToString(vm_), ""); 2363} 2364 2365HWTEST_F_L0(JSNApiTests, GetOriginalFlags) 2366{ 2367 LocalScope scope(vm_); 2368 JSThread *thread = vm_->GetJSThread(); 2369 ObjectFactory *factory = vm_->GetFactory(); 2370 auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 2371 JSHandle<JSTaggedValue> regExpFunc = globalEnv->GetRegExpFunction(); 2372 JSHandle<JSRegExp> jSRegExp = 2373 JSHandle<JSRegExp>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(regExpFunc), regExpFunc)); 2374 jSRegExp->SetOriginalFlags(thread, JSTaggedValue(RegExpParser::FLAG_GLOBAL | RegExpParser::FLAG_IGNORECASE | 2375 RegExpParser::FLAG_MULTILINE | RegExpParser::FLAG_DOTALL | 2376 RegExpParser::FLAG_UTF16 | RegExpParser::FLAG_STICKY)); 2377 Local<RegExpRef> object = JSNApiHelper::ToLocal<RegExpRef>(JSHandle<JSTaggedValue>::Cast(jSRegExp)); 2378 ASSERT_EQ(object->GetOriginalFlags(vm_), TEST_CHAR_STRING_FLAGS); 2379} 2380 2381HWTEST_F_L0(JSNApiTests, GetGeneratorState) 2382{ 2383 LocalScope scope(vm_); 2384 JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv(); 2385 ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory(); 2386 JSHandle<JSTaggedValue> genFunc = env->GetGeneratorFunctionFunction(); 2387 JSHandle<JSGeneratorObject> genObjHandleVal = factory->NewJSGeneratorObject(genFunc); 2388 genObjHandleVal->SetGeneratorState(JSGeneratorState::COMPLETED); 2389 JSHandle<JSTaggedValue> genObjTagHandleVal = JSHandle<JSTaggedValue>::Cast(genObjHandleVal); 2390 Local<GeneratorObjectRef> object = JSNApiHelper::ToLocal<GeneratorObjectRef>(genObjTagHandleVal); 2391 2392 ASSERT_EQ(object->GetGeneratorState(vm_)->ToString(vm_)->ToString(vm_), TEST_CHAR_STRING_STATE); 2393} 2394} // namespace panda::test 2395