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