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