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