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