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