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