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