1 /*
2 * Copyright (c) 2023 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_primitive_ref.h"
37 #include "ecmascript/js_regexp.h"
38 #include "ecmascript/js_runtime_options.h"
39 #include "ecmascript/js_set.h"
40 #include "ecmascript/js_set_iterator.h"
41 #include "ecmascript/js_tagged_value.h"
42 #include "ecmascript/js_thread.h"
43 #include "ecmascript/js_weak_container.h"
44 #include "ecmascript/linked_hash_table.h"
45 #include "ecmascript/mem/mem_map_allocator.h"
46 #include "ecmascript/module/js_module_manager.h"
47 #include "ecmascript/module/js_module_source_text.h"
48 #include "ecmascript/napi/include/jsnapi.h"
49 #include "ecmascript/napi/include/jsnapi_internals.h"
50 #include "ecmascript/napi/jsnapi_helper.h"
51 #include "ecmascript/object_factory.h"
52 #include "ecmascript/pgo_profiler/pgo_profiler.h"
53 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
54 #include "ecmascript/pgo_profiler/pgo_profiler_encoder.h"
55 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
56 #include "ecmascript/tagged_array.h"
57 #include "ecmascript/tests/test_helper.h"
58 #include "ecmascript/tagged_tree.h"
59 #include "ecmascript/weak_vector.h"
60 #include "gtest/gtest.h"
61
62 using namespace panda;
63 using namespace panda::ecmascript;
64 using namespace panda::ecmascript::kungfu;
65
66 static constexpr char16_t UTF_16[] = u"This is a char16 array";
67 static constexpr const char *DUPLICATE_KEY = "duplicateKey";
68 static constexpr const char *SIMPLE_KEY = "simpleKey";
69 static constexpr const char ERROR_MESSAGE[] = "ErrorTest";
70 namespace panda::test {
71 using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction;
72 using PGOProfilerManager = panda::ecmascript::pgo::PGOProfilerManager;
73 using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
74 class JSNApiTests : public testing::Test {
75 public:
SetUpTestCase()76 static void SetUpTestCase()
77 {
78 GTEST_LOG_(INFO) << "SetUpTestCase";
79 }
80
TearDownTestCase()81 static void TearDownTestCase()
82 {
83 GTEST_LOG_(INFO) << "TearDownCase";
84 }
85
SetUp()86 void SetUp() override
87 {
88 RuntimeOption option;
89 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
90 vm_ = JSNApi::CreateJSVM(option);
91 ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
92 thread_ = vm_->GetJSThread();
93 vm_->SetEnableForceGC(true);
94 thread_->ManagedCodeBegin();
95 }
96
TearDown()97 void TearDown() override
98 {
99 thread_->ManagedCodeEnd();
100 vm_->SetEnableForceGC(false);
101 JSNApi::DestroyJSVM(vm_);
102 }
103
TestNumberRef(T val,TaggedType expected)104 template <typename T> void TestNumberRef(T val, TaggedType expected)
105 {
106 LocalScope scope(vm_);
107 Local<NumberRef> obj = NumberRef::New(vm_, val);
108 ASSERT_TRUE(obj->IsNumber());
109 JSTaggedType res = JSNApiHelper::ToJSTaggedValue(*obj).GetRawData();
110 ASSERT_EQ(res, expected);
111 if constexpr (std::is_floating_point_v<T>) {
112 if (std::isnan(val)) {
113 ASSERT_TRUE(std::isnan(obj->Value()));
114 } else {
115 ASSERT_EQ(obj->Value(), val);
116 }
117 } else if constexpr (sizeof(T) >= sizeof(int32_t)) {
118 ASSERT_EQ(obj->IntegerValue(vm_), val);
119 } else if constexpr (std::is_signed_v<T>) {
120 ASSERT_EQ(obj->Int32Value(vm_), val);
121 } else {
122 ASSERT_EQ(obj->Uint32Value(vm_), val);
123 }
124 }
125
ConvertDouble(double val)126 TaggedType ConvertDouble(double val)
127 {
128 return base::bit_cast<JSTaggedType>(val) + JSTaggedValue::DOUBLE_ENCODE_OFFSET;
129 }
130
131 protected:
132 void RegisterStringCacheTable();
133
134 JSThread *thread_ = nullptr;
135 EcmaVM *vm_ = nullptr;
136 bool isStringCacheTableCreated_ = false;
137 };
138
RegisterStringCacheTable()139 void JSNApiTests::RegisterStringCacheTable()
140 {
141 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
142 auto res = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
143 if (isStringCacheTableCreated_) {
144 ASSERT_FALSE(res);
145 } else {
146 ASSERT_TRUE(res);
147 }
148 }
149
FunctionCallback(JsiRuntimeCallInfo * info)150 Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info)
151 {
152 EscapeLocalScope scope(info->GetVM());
153 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
154 }
155
WeakRefCallback(EcmaVM * vm)156 void WeakRefCallback(EcmaVM *vm)
157 {
158 LocalScope scope(vm);
159 Local<ObjectRef> object = ObjectRef::New(vm);
160 Global<ObjectRef> globalObject(vm, object);
161 globalObject.SetWeak();
162 Local<ObjectRef> object1 = ObjectRef::New(vm);
163 Global<ObjectRef> globalObject1(vm, object1);
164 globalObject1.SetWeak();
165 vm->CollectGarbage(TriggerGCType::YOUNG_GC);
166 vm->CollectGarbage(TriggerGCType::OLD_GC);
167 globalObject.FreeGlobalHandleAddr();
168 }
169
ThreadCheck(const EcmaVM * vm)170 void ThreadCheck(const EcmaVM *vm)
171 {
172 EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId());
173 }
174
CheckReject(JsiRuntimeCallInfo * info)175 void CheckReject(JsiRuntimeCallInfo *info)
176 {
177 ASSERT_EQ(info->GetArgsNumber(), 1U);
178 Local<JSValueRef> reason = info->GetCallArgRef(0);
179 ASSERT_TRUE(reason->IsString(info->GetVM()));
180 ASSERT_EQ(Local<StringRef>(reason)->ToString(info->GetVM()), "Reject");
181 }
182
RejectCallback(JsiRuntimeCallInfo * info)183 Local<JSValueRef> RejectCallback(JsiRuntimeCallInfo *info)
184 {
185 LocalScope scope(info->GetVM());
186 CheckReject(info);
187 return JSValueRef::Undefined(info->GetVM());
188 }
189
190 struct StackInfo {
191 uint64_t stackLimit;
192 uint64_t lastLeaveFrame;
193 };
194
195 /**
196 * @tc.number: ffi_interface_api_105
197 * @tc.name: JSValueRef_IsGeneratorObject
198 * @tc.desc: Determine if it is a Generator generator object
199 * @tc.type: FUNC
200 * @tc.require: parameter
201 */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsGeneratorObject)202 HWTEST_F_L0(JSNApiTests, JSValueRef_IsGeneratorObject)
203 {
204 LocalScope scope(vm_);
205 ObjectFactory *factory = vm_->GetFactory();
206 auto env = vm_->GetGlobalEnv();
207 JSHandle<JSTaggedValue> genFunc = env->GetGeneratorFunctionFunction();
208 JSHandle<JSGeneratorObject> genObjHandleVal = factory->NewJSGeneratorObject(genFunc);
209 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
210 JSHandle<JSFunction> generatorFunc = JSHandle<JSFunction>::Cast(factory->NewJSObject(hclass));
211 JSFunction::InitializeJSFunction(thread_, generatorFunc, FunctionKind::GENERATOR_FUNCTION);
212 JSHandle<GeneratorContext> generatorContext = factory->NewGeneratorContext();
213 generatorContext->SetMethod(thread_, generatorFunc.GetTaggedValue());
214 JSHandle<JSTaggedValue> generatorContextVal = JSHandle<JSTaggedValue>::Cast(generatorContext);
215 genObjHandleVal->SetGeneratorContext(thread_, generatorContextVal.GetTaggedValue());
216 JSHandle<JSTaggedValue> genObjTagHandleVal = JSHandle<JSTaggedValue>::Cast(genObjHandleVal);
217 Local<JSValueRef> genObjectRef = JSNApiHelper::ToLocal<GeneratorObjectRef>(genObjTagHandleVal);
218 ASSERT_TRUE(genObjectRef->IsGeneratorObject(vm_));
219 }
220
JSObjectTestCreate(JSThread * thread)221 static JSFunction *JSObjectTestCreate(JSThread *thread)
222 {
223 EcmaVM *ecmaVM = thread->GetEcmaVM();
224 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
225 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
226 }
227
228 /**
229 * @tc.number: ffi_interface_api_106
230 * @tc.name: JSValueRef_IsProxy
231 * @tc.desc: Determine if it is the type of proxy
232 * @tc.type: FUNC
233 * @tc.require: parameter
234 */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsProxy)235 HWTEST_F_L0(JSNApiTests, JSValueRef_IsProxy)
236 {
237 LocalScope scope(vm_);
238 JSHandle<JSTaggedValue> hclass(thread_, JSObjectTestCreate(thread_));
239 JSHandle<JSTaggedValue> targetHandle(
240 thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
241
242 JSHandle<JSTaggedValue> key(thread_->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
243 JSHandle<JSTaggedValue> value(thread_, JSTaggedValue(1));
244 JSObject::SetProperty(thread_, targetHandle, key, value);
245 EXPECT_EQ(JSObject::GetProperty(thread_, targetHandle, key).GetValue()->GetInt(), 1);
246
247 JSHandle<JSTaggedValue> handlerHandle(
248 thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
249 EXPECT_TRUE(handlerHandle->IsECMAObject());
250
251 JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread_, targetHandle, handlerHandle);
252 EXPECT_TRUE(*proxyHandle != nullptr);
253
254 EXPECT_EQ(JSProxy::GetProperty(thread_, proxyHandle, key).GetValue()->GetInt(), 1);
255 PropertyDescriptor desc(thread_);
256 JSProxy::GetOwnProperty(thread_, proxyHandle, key, desc);
257 EXPECT_EQ(desc.GetValue()->GetInt(), 1);
258 Local<JSValueRef> proxy = JSNApiHelper::ToLocal<JSProxy>(JSHandle<JSTaggedValue>(proxyHandle));
259 ASSERT_TRUE(proxy->IsProxy(vm_));
260 }
261
262 /**
263 * @tc.number: ffi_interface_api_107
264 * @tc.name: BufferRef_New_ByteLength
265 * @tc.desc:
266 * New:Create a buffer and specify the length size
267 * ByteLength:Returns the length of the buffer
268 * @tc.type: FUNC
269 * @tc.require: parameter
270 */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength)271 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength)
272 {
273 LocalScope scope(vm_);
274 int32_t length = 10;
275 Local<BufferRef> buffer = BufferRef::New(vm_, length);
276 ASSERT_TRUE(buffer->IsBuffer(vm_));
277 EXPECT_EQ(buffer->ByteLength(vm_), length);
278 }
279
280 /**
281 * @tc.number: ffi_interface_api_108
282 * @tc.name: BufferRef_New_ByteLength_GetBuffer
283 * @tc.desc:
284 * New:Create a buffer and specify the length size
285 * ByteLength:Returns the length of the buffer
286 * GetBuffer:Return buffer pointer
287 * @tc.type: FUNC
288 * @tc.require: parameter
289 */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength_GetBuffer)290 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength_GetBuffer)
291 {
292 LocalScope scope(vm_);
293 int32_t length = 10;
294 Local<BufferRef> buffer = BufferRef::New(vm_, length);
295 ASSERT_TRUE(buffer->IsBuffer(vm_));
296 EXPECT_EQ(buffer->ByteLength(vm_), 10U);
297 ASSERT_NE(buffer->GetBuffer(vm_), nullptr);
298 }
299
300 /**
301 * @tc.number: ffi_interface_api_109
302 * @tc.name: BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback
303 * @tc.desc:
304 * BufferToStringCallback:Implement callback when calling ToString (vm) mode in buffer
305 * @tc.type: FUNC
306 * @tc.require: parameter
307 */
HWTEST_F_L0(JSNApiTests,BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)308 HWTEST_F_L0(JSNApiTests, BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)
309 {
310 LocalScope scope(vm_);
311 static bool isFree = false;
312 struct Data {
313 int32_t length;
314 };
315 const int32_t length = 15;
316 NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
317 delete[] reinterpret_cast<uint8_t *>(buffer);
318 Data *currentData = reinterpret_cast<Data *>(data);
319 delete currentData;
320 isFree = true;
321 };
322 isFree = false;
323 uint8_t *buffer = new uint8_t[length]();
324 Data *data = new Data();
325 data->length = length;
326 Local<BufferRef> bufferRef = BufferRef::New(vm_, buffer, length, deleter, data);
327 ASSERT_TRUE(bufferRef->IsBuffer(vm_));
328 ASSERT_TRUE(bufferRef->IsBuffer(vm_));
329 EXPECT_EQ(bufferRef->ByteLength(vm_), 15U);
330 Local<StringRef> bufferStr = bufferRef->ToString(vm_);
331 ASSERT_TRUE(bufferStr->IsString(vm_));
332 }
333
334 /**
335 * @tc.number: ffi_interface_api_110
336 * @tc.name: LocalScope_LocalScope
337 * @tc.desc: Build Escape LocalScope sub Vm scope
338 * @tc.type: FUNC
339 * @tc.require: parameter
340 */
HWTEST_F_L0(JSNApiTests,LocalScope_LocalScope)341 HWTEST_F_L0(JSNApiTests, LocalScope_LocalScope)
342 {
343 EscapeLocalScope scope(vm_);
344 LocalScope *perScope = nullptr;
345 perScope = &scope;
346 ASSERT_TRUE(perScope != nullptr);
347 }
348
349 /**
350 * @tc.number: ffi_interface_api_111
351 * @tc.name: JSNApi_CreateJSContext_SwitchCurrentContext_DestroyJSContext
352 * @tc.desc:
353 * CreateJSContext:Create Context Object Pointer
354 * SwitchCurrentContext:Record Update Context Object
355 * DestroyJSContext:Delete Context Object
356 * @tc.type: FUNC
357 * @tc.require: parameter
358 */
HWTEST_F_L0(JSNApiTests,JSNApi_SwitchCurrentContext_DestroyJSContext)359 HWTEST_F_L0(JSNApiTests, JSNApi_SwitchCurrentContext_DestroyJSContext)
360 {
361 LocalScope scope(vm_);
362 EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 1);
363 EcmaContext *context = JSNApi::CreateJSContext(vm_);
364 GTEST_LOG_(WARNING) << "context test =" << context;
365 EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 2);
366 EcmaContext *context1 = JSNApi::CreateJSContext(vm_);
367 EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 3);
368 JSNApi::SwitchCurrentContext(vm_, context1);
369 EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 3);
370 JSNApi::DestroyJSContext(vm_, context1);
371 EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 2);
372 }
373
374 /**
375 * @tc.number: ffi_interface_api_112
376 * @tc.name: JSNApi_CreateJSVM_DestroyJSVM
377 * @tc.desc: Create/delete JSVM
378 * @tc.type: FUNC
379 * @tc.require: parameter
380 */
HWTEST_F_L0(JSNApiTests,JSNApi_CreateJSVM_DestroyJSVM)381 HWTEST_F_L0(JSNApiTests, JSNApi_CreateJSVM_DestroyJSVM)
382 {
383 LocalScope scope(vm_);
384 std::thread t1([&](){
385 EcmaVM *vm1_ = nullptr;
386 RuntimeOption option;
387 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
388 vm1_ = JSNApi::CreateJSVM(option);
389 ASSERT_TRUE(vm1_ != nullptr) << "Cannot create Runtime";
390 vm1_->SetEnableForceGC(true);
391 vm1_->SetEnableForceGC(false);
392 JSNApi::DestroyJSVM(vm1_);
393 });
394 {
395 ThreadSuspensionScope suspensionScope(thread_);
396 t1.join();
397 }
398 }
399
400 /**
401 * @tc.number: ffi_interface_api_114
402 * @tc.name: JSNApi_GetUncaughtException
403 * @tc.desc: Get uncaught exceptions
404 * @tc.type: FUNC
405 * @tc.require: parameter
406 */
HWTEST_F_L0(JSNApiTests,JSNApi_GetUncaughtException)407 HWTEST_F_L0(JSNApiTests, JSNApi_GetUncaughtException)
408 {
409 LocalScope scope(vm_);
410 Local<ObjectRef> excep = JSNApi::GetUncaughtException(vm_);
411 ASSERT_TRUE(excep.IsNull()) << "CreateInstance occur Exception";
412 }
413
FuncRefNewCallbackForTest(JsiRuntimeCallInfo * info)414 Local<JSValueRef> FuncRefNewCallbackForTest(JsiRuntimeCallInfo *info)
415 {
416 GTEST_LOG_(INFO) << "runing FuncRefNewCallbackForTest";
417 EscapeLocalScope scope(info->GetVM());
418 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
419 }
420
421 /**
422 * @tc.number: ffi_interface_api_115
423 * @tc.name: ObjectRef_SetAccessorProperty
424 * @tc.desc:
425 * SetAccessorProperty:Set AccessorPro Properties
426 * GetVM:Obtain environment information for runtime calls
427 * LocalScope:Build Vm Scope
428 * @tc.type: FUNC
429 * @tc.require: parameter
430 */
HWTEST_F_L0(JSNApiTests,ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)431 HWTEST_F_L0(JSNApiTests, ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)
432 {
433 LocalScope scope(vm_);
434 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
435 FunctionForRef nativeFunc = FuncRefNewCallbackForTest;
436 Local<FunctionRef> getter = FunctionRef::New(vm_, nativeFunc);
437 Local<FunctionRef> setter = FunctionRef::New(vm_, nativeFunc);
438 Local<ObjectRef> object = ObjectRef::New(vm_);
439 ASSERT_TRUE(object->SetAccessorProperty(vm_, key, getter, setter));
440 }
441
442 /*
443 * @tc.number: ffi_interface_api_116
444 * @tc.name: JSNApi_IsBoolean
445 * @tc.desc: Judge whether obj is a boolean type
446 * @tc.type: FUNC
447 * @tc.require: parameter
448 */
HWTEST_F_L0(JSNApiTests,IsBoolean)449 HWTEST_F_L0(JSNApiTests, IsBoolean)
450 {
451 LocalScope scope(vm_);
452 char16_t utf16[] = u"This is a char16 array";
453 int size = sizeof(utf16);
454 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
455 ASSERT_FALSE(obj->IsBoolean());
456 }
457
458 /*
459 * @tc.number: ffi_interface_api_117
460 * @tc.name: JSNApi_IsNULL
461 * @tc.desc: Judge whether obj is a null type
462 * @tc.type: FUNC
463 * @tc.require: parameter
464 */
HWTEST_F_L0(JSNApiTests,IsNULL)465 HWTEST_F_L0(JSNApiTests, IsNULL)
466 {
467 LocalScope scope(vm_);
468 char16_t utf16[] = u"This is a char16 array";
469 int size = sizeof(utf16);
470 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
471 ASSERT_FALSE(obj->IsNull());
472 }
473
474 /*
475 * @tc.number: ffi_interface_api_118
476 * @tc.name: JSNApi_GetTime
477 * @tc.desc: This function is to catch time
478 * @tc.type: FUNC
479 * @tc.require: parameter
480 */
HWTEST_F_L0(JSNApiTests,GetTime)481 HWTEST_F_L0(JSNApiTests, GetTime)
482 {
483 LocalScope scope(vm_);
484 const double time = 14.29;
485 Local<DateRef> date = DateRef::New(vm_, time);
486 ASSERT_EQ(date->GetTime(vm_), time);
487 }
488
489 /*
490 * @tc.number: ffi_interface_api_119
491 * @tc.name: JSNApi_IsDetach
492 * @tc.desc: Judge whether arraybuffer is detached
493 * @tc.type: FUNC
494 * @tc.require: parameter
495 */
HWTEST_F_L0(JSNApiTests,IsDetach)496 HWTEST_F_L0(JSNApiTests, IsDetach)
497 {
498 LocalScope scope(vm_);
499 const int32_t length = 33;
500 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
501 ASSERT_FALSE(arraybuffer->IsDetach(vm_));
502 }
503
504 /*
505 * @tc.number: ffi_interface_api_120
506 * @tc.name: JSNApi_Detach
507 * @tc.desc: This function is to detach arraybuffer
508 * @tc.type: FUNC
509 * @tc.require: parameter
510 */
HWTEST_F_L0(JSNApiTests,Detach)511 HWTEST_F_L0(JSNApiTests, Detach)
512 {
513 LocalScope scope(vm_);
514 const int32_t length = 33;
515 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
516 arraybuffer->Detach(vm_);
517 }
518
519 /*
520 * @tc.number: ffi_interface_api_121
521 * @tc.name: JSNApi_New1
522 * @tc.desc: create a obj that is a arraybuffer type
523 * @tc.type: FUNC
524 * @tc.require: parameter
525 */
HWTEST_F_L0(JSNApiTests,New1)526 HWTEST_F_L0(JSNApiTests, New1)
527 {
528 LocalScope scope(vm_);
529 const int32_t length = 33;
530 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
531 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
532 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
533 ASSERT_NE(arrayBuffer->GetBuffer(vm_), nullptr);
534 }
535
536 /*
537 * @tc.number: ffi_interface_api_122
538 * @tc.name: JSNApi_New1
539 * @tc.desc: create a obj that is a arraybuffer type
540 * @tc.type: FUNC
541 * @tc.require: parameter
542 */
HWTEST_F_L0(JSNApiTests,New2)543 HWTEST_F_L0(JSNApiTests, New2)
544 {
545 static bool isFree = false;
546 struct Data {
547 int32_t length;
548 };
549 const int32_t length = 15;
550 Data *data = new Data();
551 data->length = length;
552 NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
553 delete[] reinterpret_cast<uint8_t *>(buffer);
554 Data *currentData = reinterpret_cast<Data *>(data);
555 ASSERT_EQ(currentData->length, 15); // 5 : size of arguments
556 delete currentData;
557 isFree = true;
558 };
559 {
560 LocalScope scope(vm_);
561 uint8_t *buffer = new uint8_t[length]();
562 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
563 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
564 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
565 ASSERT_EQ(arrayBuffer->GetBuffer(vm_), buffer);
566 }
567 }
568
569 /*
570 * @tc.number: ffi_interface_api_123
571 * @tc.name: JSNApi_Bytelength
572 * @tc.desc: capture bytelength of arraybuffer
573 * @tc.type: FUNC
574 * @tc.require: parameter
575 */
HWTEST_F_L0(JSNApiTests,Bytelength)576 HWTEST_F_L0(JSNApiTests, Bytelength)
577 {
578 LocalScope scope(vm_);
579 const int32_t length = 33;
580 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
581 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
582 }
583
584 /*
585 * @tc.number: ffi_interface_api_124
586 * @tc.name: JSNApi_GetBuffer
587 * @tc.desc: capture buffer of arraybuffer
588 * @tc.type: FUNC
589 * @tc.require: parameter
590 */
HWTEST_F_L0(JSNApiTests,GetBuffer)591 HWTEST_F_L0(JSNApiTests, GetBuffer)
592 {
593 LocalScope scope(vm_);
594 const int32_t length = 33;
595 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
596 ASSERT_NE(arraybuffer->GetBuffer(vm_), nullptr);
597 }
598
599 /*
600 * @tc.number: ffi_interface_api_125
601 * @tc.name: JSNApi_Is32Arraytest
602 * @tc.desc: judge whether obj is a int32array type,
603 * judge whether obj is a uint32array type,
604 * judge whether obj is a float32array type,
605 * judge whether obj is a float64array type,
606 * @tc.type: FUNC
607 * @tc.require: parameter
608 */
HWTEST_F_L0(JSNApiTests,Is32Arraytest)609 HWTEST_F_L0(JSNApiTests, Is32Arraytest)
610 {
611 LocalScope scope(vm_);
612 char16_t utf16[] = u"This is a char16 array";
613 int size = sizeof(utf16);
614 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
615 ASSERT_FALSE(obj->IsInt32Array(vm_));
616 ASSERT_FALSE(obj->IsUint32Array(vm_));
617 ASSERT_FALSE(obj->IsFloat32Array(vm_));
618 ASSERT_FALSE(obj->IsFloat64Array(vm_));
619 }
620
621 /*
622 * @tc.number: ffi_interface_api_126
623 * @tc.name: JSNApi_SynchronizVMInfo
624 * @tc.desc: capture synchronous info of vm
625 * @tc.type: FUNC
626 * @tc.require: parameter
627 */
HWTEST_F_L0(JSNApiTests,SynchronizVMInfo)628 HWTEST_F_L0(JSNApiTests, SynchronizVMInfo)
629 {
630 LocalScope scope(vm_);
631 std::thread t1([&]() {
632 JSRuntimeOptions option;
633 EcmaVM *hostVM = JSNApi::CreateEcmaVM(option);
634 {
635 LocalScope scope2(hostVM);
636 JSNApi::SynchronizVMInfo(vm_, hostVM);
637 }
638 JSNApi::DestroyJSVM(hostVM);
639 });
640 {
641 ThreadSuspensionScope suspensionScope(thread_);
642 t1.join();
643 }
644 }
645
646 /*
647 * @tc.number: ffi_interface_api_127
648 * @tc.name: JSNApi_IsProfiling
649 * @tc.desc: judge whether vm is profiling
650 * @tc.type: FUNC
651 * @tc.require: parameter
652 */
HWTEST_F_L0(JSNApiTests,IsProfiling)653 HWTEST_F_L0(JSNApiTests, IsProfiling)
654 {
655 LocalScope scope(vm_);
656 ASSERT_FALSE(JSNApi::IsProfiling(vm_));
657 }
658
659 /*
660 * @tc.number: ffi_interface_api_128
661 * @tc.name: JSNApi_SetProfilerState
662 * @tc.desc: This function is to set state of profiler
663 * @tc.type: FUNC
664 * @tc.require: parameter
665 */
HWTEST_F_L0(JSNApiTests,SetProfilerState)666 HWTEST_F_L0(JSNApiTests, SetProfilerState)
667 {
668 bool value = true;
669 bool value2 = false;
670 LocalScope scope(vm_);
671 JSNApi::SetProfilerState(vm_, value);
672 JSNApi::SetProfilerState(vm_, value2);
673 }
674
675 /*
676 * @tc.number: ffi_interface_api_129
677 * @tc.name: JSNApi_SetLoop
678 * @tc.desc: This function is to set loop
679 * @tc.type: FUNC
680 * @tc.require: parameter
681 */
HWTEST_F_L0(JSNApiTests,SetLoop)682 HWTEST_F_L0(JSNApiTests, SetLoop)
683 {
684 LocalScope scope(vm_);
685 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
686 JSNApi::SetLoop(vm_, data);
687 }
688
689 /*
690 * @tc.number: ffi_interface_api_130
691 * @tc.name: JSNApi_SetHostPromiseRejectionTracker
692 * @tc.desc: This function is to set host promise rejection about tracker
693 * @tc.type: FUNC
694 * @tc.require: parameter
695 */
HWTEST_F_L0(JSNApiTests,SetHostPromiseRejectionTracker)696 HWTEST_F_L0(JSNApiTests, SetHostPromiseRejectionTracker)
697 {
698 LocalScope scope(vm_);
699 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
700 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
701 JSNApi::SetHostPromiseRejectionTracker(vm_, cb, data);
702 }
703
704 /*
705 * @tc.number: ffi_interface_api_131
706 * @tc.name: JSNApi_SetHostResolveBufferTracker
707 * @tc.desc: This function is to set host resolve buffer about tracker
708 * @tc.type: FUNC
709 * @tc.require: parameter
710 */
HWTEST_F_L0(JSNApiTests,SetHostResolveBufferTracker)711 HWTEST_F_L0(JSNApiTests, SetHostResolveBufferTracker)
712 {
713 LocalScope scope(vm_);
714 JSNApi::SetHostResolveBufferTracker(vm_,
715 [&](std::string, uint8_t **, size_t *, std::string &) -> bool { return true; });
716 }
717
718 /*
719 * @tc.number: ffi_interface_api_132
720 * @tc.name: JSNApi_SetUnloadNativeModuleCallback
721 * @tc.desc: This function is to set unload native module about callback
722 * @tc.type: FUNC
723 * @tc.require: parameter
724 */
HWTEST_F_L0(JSNApiTests,SetUnloadNativeModuleCallback)725 HWTEST_F_L0(JSNApiTests, SetUnloadNativeModuleCallback)
726 {
727 LocalScope scope(vm_);
728 JSNApi::SetUnloadNativeModuleCallback(vm_, [&](const std::string &) -> bool { return true; });
729 }
730
731 /*
732 * @tc.number: ffi_interface_api_133
733 * @tc.name: JSNApi_SetNativePtrGetter
734 * @tc.desc: This function is to set a native pointer about getter
735 * @tc.type: FUNC
736 * @tc.require: parameter
737 */
HWTEST_F_L0(JSNApiTests,SetNativePtrGetter)738 HWTEST_F_L0(JSNApiTests, SetNativePtrGetter)
739 {
740 LocalScope scope(vm_);
741 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
742 JSNApi::SetNativePtrGetter(vm_, cb);
743 }
744
745 /*
746 * @tc.number: ffi_interface_api_134
747 * @tc.name: JSNApi_PreFork
748 * @tc.desc: This function is to set prefork
749 * @tc.type: FUNC
750 * @tc.require: parameter
751 */
HWTEST_F_L0(JSNApiTests,PreFork)752 HWTEST_F_L0(JSNApiTests, PreFork)
753 {
754 RuntimeOption option;
755 ecmascript::ThreadNativeScope nativeScope(vm_->GetJSThread());
756 LocalScope scope(vm_);
757 JSNApi::PreFork(vm_);
758 JSNApi::PostFork(vm_, option);
759 }
760
761 /*
762 * @tc.number: ffi_interface_api_135
763 * @tc.name: JSNApi_PostFork
764 * @tc.desc: This function is to set postfork
765 * @tc.type: FUNC
766 * @tc.require: parameter
767 */
HWTEST_F_L0(JSNApiTests,PostFork)768 HWTEST_F_L0(JSNApiTests, PostFork)
769 {
770 RuntimeOption option;
771 ecmascript::ThreadNativeScope nativeScope(vm_->GetJSThread());
772 LocalScope scope(vm_);
773 JSNApi::PreFork(vm_);
774 JSNApi::PostFork(vm_, option);
775 }
776
777
778 /*
779 * @tc.number: ffi_interface_api_136
780 * @tc.name: JSNApi_NewFromUtf8
781 * @tc.desc: create a newfromutf8 object
782 * @tc.type: FUNC
783 * @tc.require: parameter
784 */
HWTEST_F_L0(JSNApiTests,NewFromUtf8)785 HWTEST_F_L0(JSNApiTests, NewFromUtf8)
786 {
787 LocalScope scope(vm_);
788 char utf8[] = "hello world!";
789 int length = strlen(utf8);
790 Local<StringRef> result = StringRef::NewFromUtf8(vm_, utf8, length);
791 ASSERT_EQ(result->Utf8Length(vm_), length + 1);
792 }
793
794 /*
795 * @tc.number: ffi_interface_api_137
796 * @tc.name: JSNApi_NewFromUtf16
797 * @tc.desc: create a newfromutf16 object
798 * @tc.type: FUNC
799 * @tc.require: parameter
800 */
HWTEST_F_L0(JSNApiTests,NewFromUtf16)801 HWTEST_F_L0(JSNApiTests, NewFromUtf16)
802 {
803 LocalScope scope(vm_);
804 char16_t utf16[] = u"This is a char16 array";
805 int length = sizeof(utf16);
806 Local<StringRef> result = StringRef::NewFromUtf16(vm_, utf16, length);
807 ASSERT_EQ(result->Length(vm_), length);
808 }
809
810 /*
811 * @tc.number: ffi_interface_api_138
812 * @tc.name: JSNApi_GetNapiWrapperString
813 * @tc.desc: This function is to get a napiwrapper string
814 * @tc.type: FUNC
815 * @tc.require: parameter
816 */
HWTEST_F_L0(JSNApiTests,GetNapiWrapperString)817 HWTEST_F_L0(JSNApiTests, GetNapiWrapperString)
818 {
819 LocalScope scope(vm_);
820 Local<StringRef> result = StringRef::GetNapiWrapperString(vm_);
821 ASSERT_TRUE(result->IsString(vm_));
822 }
823
824 /*
825 * @tc.number: ffi_interface_api_139
826 * @tc.name: JSNApi_JSExecutionScope
827 * @tc.desc: This function is to construct a object of jsexecutionscope
828 * @tc.type: FUNC
829 * @tc.require: parameter
830 */
HWTEST_F_L0(JSNApiTests,JSExecutionScope)831 HWTEST_F_L0(JSNApiTests, JSExecutionScope)
832 {
833 LocalScope scope(vm_);
834 JSExecutionScope jsexecutionScope(vm_);
835 }
836
837 /*
838 * @tc.number: ffi_interface_api_140
839 * @tc.name: WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue
840 * @tc.desc: This function is to set a weakmap and capture it's size ,
841 * key, value and total elements
842 * @tc.type: FUNC
843 * @tc.require: parameter
844 */
HWTEST_F_L0(JSNApiTests,WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)845 HWTEST_F_L0(JSNApiTests, WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)
846 {
847 LocalScope scope(vm_);
848 JSThread *thread = vm_->GetJSThread();
849 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
850 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
851 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakMapFunction();
852 JSHandle<JSWeakMap> weakMap =
853 JSHandle<JSWeakMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
854 JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
855 weakMap->SetLinkedMap(thread, hashMap);
856 JSHandle<JSTaggedValue> weakMapTag = JSHandle<JSTaggedValue>::Cast(weakMap);
857
858 Local<WeakMapRef> map = JSNApiHelper::ToLocal<WeakMapRef>(weakMapTag);
859 EXPECT_TRUE(map->IsWeakMap(vm_));
860 JSHandle<JSTaggedValue> value(factory->NewFromASCII("value"));
861 JSHandle<JSTaggedValue> key(factory->NewFromASCII("key"));
862 JSWeakMap::Set(thread, weakMap, key, value);
863 int32_t num = map->GetSize(vm_);
864 int32_t num1 = map->GetTotalElements(vm_);
865 ASSERT_EQ(num, 1);
866 ASSERT_EQ(num1, 1);
867 Local<JSValueRef> res1 = map->GetKey(vm_, 0);
868 ASSERT_EQ(res1->ToString(vm_)->ToString(vm_), "key");
869 Local<JSValueRef> res2 = map->GetValue(vm_, 0);
870 ASSERT_EQ(res2->ToString(vm_)->ToString(vm_), "value");
871 }
872
873 /*
874 * @tc.number: ffi_interface_api_141
875 * @tc.name: JSNApi_ IsAGJA
876 * @tc.desc: This function is to judge whether object is a argumentsobject or
877 * is a generatorfunction or is a asyncfunction
878 * @tc.type: FUNC
879 * @tc.require: parameter
880 */
HWTEST_F_L0(JSNApiTests,IsAGJA)881 HWTEST_F_L0(JSNApiTests, IsAGJA)
882 {
883 LocalScope scope(vm_);
884 char16_t utf16[] = u"This is a char16 array";
885 int size = sizeof(utf16);
886 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
887 ASSERT_FALSE(obj->IsArgumentsObject(vm_));
888 ASSERT_FALSE(obj->IsGeneratorFunction(vm_));
889 ASSERT_FALSE(obj->IsAsyncFunction(vm_));
890 }
891
892 /**
893 * @tc.number: ffi_interface_api_143
894 * @tc.name: Int32Array
895 * @tc.desc: Catch exceptions correctly
896 * @tc.type: FUNC
897 * @tc.require: parameter
898 */
HWTEST_F_L0(JSNApiTests,HasCaught)899 HWTEST_F_L0(JSNApiTests, HasCaught)
900 {
901 LocalScope scope(vm_);
902 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
903 Local<JSValueRef> error = Exception::Error(vm_, message);
904 ASSERT_TRUE(error->IsError(vm_));
905 JSNApi::ThrowException(vm_, error);
906 TryCatch tryCatch(vm_);
907 ASSERT_TRUE(tryCatch.HasCaught());
908 vm_->GetJSThread()->ClearException();
909 ASSERT_FALSE(tryCatch.HasCaught());
910 }
911
912 /**
913 * @tc.number: ffi_interface_api_144
914 * @tc.name: Int32Array
915 * @tc.desc: Rethrow the exception
916 * @tc.type: FUNC
917 * @tc.require: parameter
918 */
HWTEST_F_L0(JSNApiTests,Rethrow)919 HWTEST_F_L0(JSNApiTests, Rethrow)
920 {
921 LocalScope scope(vm_);
922 TryCatch tryCatch(vm_);
923 tryCatch.Rethrow();
924 ASSERT_TRUE(tryCatch.getrethrow_());
925 }
926
927 /**
928 * @tc.number: ffi_interface_api_145
929 * @tc.name: Int32Array
930 * @tc.desc: Clear caught exceptions
931 * @tc.type: FUNC
932 * @tc.require: parameter
933 */
HWTEST_F_L0(JSNApiTests,GetAndClearException)934 HWTEST_F_L0(JSNApiTests, GetAndClearException)
935 {
936 LocalScope scope(vm_);
937 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
938 Local<JSValueRef> error = Exception::Error(vm_, message);
939 ASSERT_TRUE(error->IsError(vm_));
940 JSNApi::ThrowException(vm_, error);
941 ASSERT_TRUE(vm_->GetJSThread()->HasPendingException());
942 TryCatch tryCatch(vm_);
943 tryCatch.GetAndClearException();
944 EXPECT_FALSE(vm_->GetJSThread()->HasPendingException());
945 }
946 /**
947 * @tc.number: ffi_interface_api_146
948 * @tc.name: Int32Array
949 * @tc.desc: trycatch class construction
950 * @tc.type: FUNC
951 * @tc.require: parameter
952 */
HWTEST_F_L0(JSNApiTests,TryCatch)953 HWTEST_F_L0(JSNApiTests, TryCatch)
954 {
955 LocalScope scope(vm_);
956 TryCatch tryCatch(vm_);
957 EXPECT_EQ(tryCatch.getrethrow_(), false);
958 EXPECT_FALSE(tryCatch.HasCaught());
959 tryCatch.Rethrow();
960 EXPECT_EQ(tryCatch.getrethrow_(), true);
961 }
962
HWTEST_F_L0(JSNApiTests,NewObjectWithProperties)963 HWTEST_F_L0(JSNApiTests, NewObjectWithProperties)
964 {
965 LocalScope scope(vm_);
966 Local<JSValueRef> keys[1100];
967 Local<JSValueRef> values[1100];
968 PropertyAttribute attributes[1100];
969 for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
970 for (int j = 0; j <= i; ++j) {
971 std::string strKey("TestKey" + std::to_string(i) + "_" + std::to_string(j));
972 std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
973 keys[j] = StringRef::NewFromUtf8(vm_, strKey.c_str());
974 values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
975 attributes[j] = PropertyAttribute(values[j], true, true, true);
976 }
977 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, i + 1, keys, attributes);
978 for (int j = 0; j <= i; ++j) {
979 Local<JSValueRef> value1 = object->Get(vm_, keys[j]);
980 EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
981 }
982 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
983 uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
984 if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
985 EXPECT_TRUE(propCount == 0);
986 EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
987 JSHandle<NameDictionary> dict(thread_, obj->GetProperties());
988 EXPECT_TRUE(dict->EntriesCount() == i + 1);
989 } else {
990 EXPECT_TRUE(propCount == i + 1);
991 int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
992 int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
993 if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
994 EXPECT_TRUE(in_idx == i + 1);
995 EXPECT_TRUE(nonin_idx == -1);
996 } else {
997 EXPECT_TRUE(in_idx == -1);
998 EXPECT_TRUE(nonin_idx == 0);
999 }
1000 }
1001 }
1002 }
1003
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertieNonPureStringKey)1004 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertieNonPureStringKey)
1005 {
1006 LocalScope scope(vm_);
1007 Local<JSValueRef> keys[] = {
1008 StringRef::NewFromUtf8(vm_, "1"),
1009 };
1010 Local<JSValueRef> values[] = {
1011 StringRef::NewFromUtf8(vm_, "value1"),
1012 };
1013 PropertyAttribute attributes[] = {
1014 PropertyAttribute(values[0], true, true, true),
1015 };
1016 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 1, keys, attributes);
1017 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1018 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1019 thread_->ClearException();
1020 }
1021
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicate)1022 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicate)
1023 {
1024 LocalScope scope(vm_);
1025 Local<JSValueRef> keys[] = {
1026 StringRef::NewFromUtf8(vm_, DUPLICATE_KEY),
1027 StringRef::NewFromUtf8(vm_, SIMPLE_KEY),
1028 StringRef::NewFromUtf8(vm_, DUPLICATE_KEY),
1029 };
1030 Local<JSValueRef> values[] = {
1031 StringRef::NewFromUtf8(vm_, "value1"),
1032 StringRef::NewFromUtf8(vm_, "value2"),
1033 StringRef::NewFromUtf8(vm_, "value3"),
1034 };
1035 PropertyAttribute attributes[] = {
1036 PropertyAttribute(values[0], true, true, true),
1037 PropertyAttribute(values[1], true, true, true),
1038 PropertyAttribute(values[2], true, true, true),
1039 };
1040 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1041 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1042 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1043 thread_->ClearException();
1044 }
1045
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedProperties)1046 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedProperties)
1047 {
1048 LocalScope scope(vm_);
1049 const char *keys[1100];
1050 std::string strKeys[1100];
1051 Local<JSValueRef> values[1100];
1052 for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
1053 for (int j = 0; j <= i; ++j) {
1054 strKeys[j] = "TestKey" + std::to_string(i) + "_" + std::to_string(j);
1055 std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
1056 keys[j] = const_cast<char *>(strKeys[j].c_str());
1057 values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
1058 }
1059 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, i + 1, keys, values);
1060 for (int j = 0; j <= i; ++j) {
1061 Local<JSValueRef> value1 = object->Get(vm_, StringRef::NewFromUtf8(vm_, keys[j]));
1062 EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
1063 }
1064 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
1065 uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
1066 if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
1067 EXPECT_TRUE(propCount == 0);
1068 EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
1069 JSHandle<NameDictionary> dict(thread_, obj->GetProperties());
1070 EXPECT_TRUE(dict->EntriesCount() == i + 1);
1071 } else {
1072 EXPECT_TRUE(propCount == i + 1);
1073 int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
1074 int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
1075 if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
1076 EXPECT_TRUE(in_idx == i + 1);
1077 EXPECT_TRUE(nonin_idx == -1);
1078 } else {
1079 EXPECT_TRUE(in_idx == -1);
1080 EXPECT_TRUE(nonin_idx == 0);
1081 }
1082 }
1083 }
1084 }
1085
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertieNonPureStringKey)1086 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertieNonPureStringKey)
1087 {
1088 LocalScope scope(vm_);
1089 const char *keys[] = {
1090 "1",
1091 };
1092 Local<JSValueRef> values[] = {
1093 StringRef::NewFromUtf8(vm_, "value1"),
1094 };
1095 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 2, keys, values);
1096 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1097 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1098 thread_->ClearException();
1099 }
1100
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertiesDuplicate)1101 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertiesDuplicate)
1102 {
1103 LocalScope scope(vm_);
1104 const char *keys[] = {
1105 DUPLICATE_KEY,
1106 SIMPLE_KEY,
1107 DUPLICATE_KEY,
1108 };
1109 Local<JSValueRef> values[] = {
1110 StringRef::NewFromUtf8(vm_, "value1"),
1111 StringRef::NewFromUtf8(vm_, "value2"),
1112 StringRef::NewFromUtf8(vm_, "value3"),
1113 };
1114 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 3, keys, values);
1115 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1116 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1117 thread_->ClearException();
1118 }
1119
HWTEST_F_L0(JSNApiTests,GetNamedPropertyByPassingUtf8Key)1120 HWTEST_F_L0(JSNApiTests, GetNamedPropertyByPassingUtf8Key)
1121 {
1122 LocalScope scope(vm_);
1123 Local<ObjectRef> object = ObjectRef::New(vm_);
1124 const char* utf8Key = "TestKey";
1125 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1126 Local<JSValueRef> value = ObjectRef::New(vm_);
1127 PropertyAttribute attribute(value, true, true, true);
1128
1129 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1130 Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1131 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1132 }
1133
HWTEST_F_L0(JSNApiTests,SetNamedPropertyByPassingUtf8Key)1134 HWTEST_F_L0(JSNApiTests, SetNamedPropertyByPassingUtf8Key)
1135 {
1136 LocalScope scope(vm_);
1137 Local<ObjectRef> object = ObjectRef::New(vm_);
1138 const char* utf8Key = "TestKey";
1139 Local<JSValueRef> value = ObjectRef::New(vm_);
1140
1141 ASSERT_TRUE(object->Set(vm_, utf8Key, value));
1142 Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1143 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1144 }
1145
HWTEST_F_L0(JSNApiTests,NapiFastPathGetNamedProperty)1146 HWTEST_F_L0(JSNApiTests, NapiFastPathGetNamedProperty)
1147 {
1148 LocalScope scope(vm_);
1149 Local<ObjectRef> object = ObjectRef::New(vm_);
1150 const char* utf8Key = "TestKey";
1151 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1152 Local<JSValueRef> value = ObjectRef::New(vm_);
1153 PropertyAttribute attribute(value, true, true, true);
1154
1155 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1156 Local<JSValueRef> value1 = JSNApi::NapiGetNamedProperty(vm_, reinterpret_cast<uintptr_t>(*object), utf8Key);
1157 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1158 }
1159
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)1160 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)
1161 {
1162 LocalScope scope(vm_);
1163 Local<JSValueRef> keys[] = {
1164 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY),
1165 StringRef::NewFromUtf8WithoutStringTable(vm_, SIMPLE_KEY),
1166 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY),
1167 };
1168 Local<JSValueRef> values[] = {
1169 StringRef::NewFromUtf8WithoutStringTable(vm_, "value1"),
1170 StringRef::NewFromUtf8WithoutStringTable(vm_, "value2"),
1171 StringRef::NewFromUtf8WithoutStringTable(vm_, "value3"),
1172 };
1173 PropertyAttribute attributes[] = {
1174 PropertyAttribute(values[0], true, true, true),
1175 PropertyAttribute(values[1], true, true, true),
1176 PropertyAttribute(values[2], true, true, true),
1177 };
1178 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1179 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1180 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1181 thread_->ClearException();
1182 }
1183
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable1)1184 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable1)
1185 {
1186 LocalScope scope(vm_);
1187 Local<JSValueRef> keys[] = {
1188 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY, 0),
1189 StringRef::NewFromUtf8WithoutStringTable(vm_, SIMPLE_KEY, 0),
1190 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY, 0),
1191 };
1192 Local<JSValueRef> values[] = {
1193 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1194 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1195 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1196 };
1197 PropertyAttribute attributes[] = {
1198 PropertyAttribute(values[0], true, true, true),
1199 PropertyAttribute(values[1], true, true, true),
1200 PropertyAttribute(values[2], true, true, true),
1201 };
1202 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1203 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1204 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1205 thread_->ClearException();
1206 }
1207
HWTEST_F_L0(JSNApiTests,EcmaObjectToInt)1208 HWTEST_F_L0(JSNApiTests, EcmaObjectToInt)
1209 {
1210 LocalScope scope(vm_);
1211 Local<FunctionRef> toPrimitiveFunc = FunctionRef::New(vm_,
1212 [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1213 EcmaVM *vm = runtimeInfo->GetVM();
1214 return JSValueRef::True(vm);
1215 });
1216 Local<ObjectRef> obj = ObjectRef::New(vm_);
1217 PropertyAttribute attribute(toPrimitiveFunc, true, true, true);
1218 Local<JSValueRef> toPrimitiveKey = JSNApiHelper::ToLocal<JSValueRef>(vm_->GetGlobalEnv()->GetToPrimitiveSymbol());
1219 obj->DefineProperty(vm_, toPrimitiveKey, attribute);
1220 {
1221 // Test that Uint32Value and Int32Value should transition to Running if needed.
1222 ThreadNativeScope nativeScope(thread_);
1223 uint32_t res = obj->Uint32Value(vm_);
1224 EXPECT_TRUE(res == 1);
1225 res = obj->Int32Value(vm_);
1226 EXPECT_TRUE(res == 1);
1227 }
1228 }
1229
HWTEST_F_L0(JSNApiTests,NapiTryFastTest)1230 HWTEST_F_L0(JSNApiTests, NapiTryFastTest)
1231 {
1232 Local<ObjectRef> object = ObjectRef::New(vm_);
1233 JSTaggedValue a(0);
1234 JSHandle<JSTaggedValue> handle(thread_, a);
1235 Local<JSValueRef> key = JSNApiHelper::ToLocal<JSValueRef>(handle);
1236 const char* utf8Key = "TestKey";
1237 Local<JSValueRef> key2 = StringRef::NewFromUtf8(vm_, utf8Key);
1238 Local<JSValueRef> value = ObjectRef::New(vm_);
1239 object->Set(vm_, key, value);
1240 object->Set(vm_, key2, value);
1241 Local<JSValueRef> res1 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1242 reinterpret_cast<uintptr_t>(*key));
1243 ASSERT_TRUE(value->IsStrictEquals(vm_, res1));
1244 Local<JSValueRef> res2 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1245 reinterpret_cast<uintptr_t>(*key2));
1246 ASSERT_TRUE(value->IsStrictEquals(vm_, res2));
1247
1248 Local<JSValueRef> flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1249 reinterpret_cast<uintptr_t>(*key));
1250 ASSERT_TRUE(flag->BooleaValue(vm_));
1251 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1252 ASSERT_TRUE(flag->BooleaValue(vm_));
1253
1254 flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1255 ASSERT_TRUE(flag->BooleaValue(vm_));
1256 flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1257 ASSERT_TRUE(flag->BooleaValue(vm_));
1258
1259 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1260 ASSERT_FALSE(flag->BooleaValue(vm_));
1261 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1262 ASSERT_FALSE(flag->BooleaValue(vm_));
1263 }
1264
HWTEST_F_L0(JSNApiTests,NapiTryFastHasMethodTest)1265 HWTEST_F_L0(JSNApiTests, NapiTryFastHasMethodTest)
1266 {
1267 LocalScope scope(vm_);
1268 auto array = JSArray::ArrayCreate(thread_, JSTaggedNumber(0));
1269 auto arr = JSNApiHelper::ToLocal<ObjectRef>(array);
1270 const char* utf8Key = "concat";
1271 Local<JSValueRef> key3 = StringRef::NewFromUtf8(vm_, utf8Key);
1272 auto flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*arr), reinterpret_cast<uintptr_t>(*key3));
1273 ASSERT_TRUE(flag->BooleaValue(vm_));
1274 }
1275
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest001)1276 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest001)
1277 {
1278 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, 0);
1279 ASSERT_FALSE(isStringCacheTableCreated_);
1280 }
1281
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest002)1282 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest002)
1283 {
1284 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 300;
1285 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1286 ASSERT_FALSE(isStringCacheTableCreated_);
1287 }
1288
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest003)1289 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest003)
1290 {
1291 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
1292 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1293 ASSERT_TRUE(isStringCacheTableCreated_);
1294 }
1295
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest004)1296 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest004)
1297 {
1298 RegisterStringCacheTable();
1299 constexpr uint32_t PROPERTY_INDEX = 101;
1300 constexpr char property[] = "hello";
1301 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1302 ASSERT_FALSE(res);
1303 }
1304
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest005)1305 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest005)
1306 {
1307 RegisterStringCacheTable();
1308 constexpr uint32_t PROPERTY_INDEX = 0;
1309 constexpr char property[] = "hello";
1310 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1311 ASSERT_TRUE(res);
1312 }
1313
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest006)1314 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest006)
1315 {
1316 RegisterStringCacheTable();
1317 constexpr uint32_t PROPERTY_INDEX = 1;
1318 constexpr char property[] = "hello";
1319 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1320 ASSERT_TRUE(res);
1321
1322 constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1323 res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1324 ASSERT_FALSE(res);
1325 }
1326
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest007)1327 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest007)
1328 {
1329 RegisterStringCacheTable();
1330 constexpr uint32_t PROPERTY_INDEX = 2;
1331 constexpr char property[] = "hello";
1332 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1333 ASSERT_TRUE(res);
1334
1335 constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1336 res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1337 ASSERT_TRUE(res);
1338 }
1339
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest008)1340 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest008)
1341 {
1342 RegisterStringCacheTable();
1343 constexpr uint32_t PROPERTY_INDEX = 3;
1344 constexpr char property[] = "hello world";
1345 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1346 ASSERT_TRUE(res);
1347 Local<StringRef> value = ExternalStringCache::GetCachedString(vm_, PROPERTY_INDEX);
1348 ASSERT_FALSE(value->IsUndefined());
1349 EXPECT_EQ(value->ToString(vm_), property);
1350 }
1351
HWTEST_F_L0(JSNApiTests,SetExecuteMode)1352 HWTEST_F_L0(JSNApiTests, SetExecuteMode)
1353 {
1354 ecmascript::ModuleManager *moduleManager = thread_->GetCurrentEcmaContext()->GetModuleManager();
1355 ecmascript::ModuleExecuteMode res1 = moduleManager->GetExecuteMode();
1356 EXPECT_EQ(res1, ecmascript::ModuleExecuteMode::ExecuteZipMode);
1357
1358 JSNApi::SetExecuteBufferMode(vm_);
1359 ecmascript::ModuleExecuteMode res2 = moduleManager->GetExecuteMode();
1360 EXPECT_EQ(res2, ecmascript::ModuleExecuteMode::ExecuteBufferMode);
1361 }
1362
HWTEST_F_L0(JSNApiTests,ToEcmaObject)1363 HWTEST_F_L0(JSNApiTests, ToEcmaObject)
1364 {
1365 LocalScope scope(vm_);
1366 Local<ObjectRef> res = ObjectRef::New(vm_);
1367 res->ToEcmaObject(vm_);
1368 ASSERT_TRUE(res->IsObject(vm_));
1369 }
1370
HWTEST_F_L0(JSNApiTests,GetValueInt64)1371 HWTEST_F_L0(JSNApiTests, GetValueInt64)
1372 {
1373 LocalScope scope(vm_);
1374 bool isNumber = true;
1375 int32_t input = 4;
1376 Local<IntegerRef> res = IntegerRef::New(vm_, input);
1377 res->ToBigInt(vm_);
1378 ASSERT_TRUE(res->GetValueInt64(isNumber));
1379 res->ToNumber(vm_);
1380 ASSERT_TRUE(res->GetValueInt64(isNumber));
1381 isNumber = false;
1382 ASSERT_TRUE(res->GetValueInt64(isNumber));
1383 }
1384
HWTEST_F_L0(JSNApiTests,GetDataViewInfo)1385 HWTEST_F_L0(JSNApiTests, GetDataViewInfo)
1386 {
1387 LocalScope scope(vm_);
1388 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
1389 bool isDataView = false;
1390 key->GetDataViewInfo(vm_, isDataView, nullptr, nullptr, nullptr, nullptr);
1391 ASSERT_FALSE(isDataView);
1392 isDataView = true;
1393 key->GetDataViewInfo(vm_, isDataView, nullptr, nullptr, nullptr, nullptr);
1394 ASSERT_FALSE(isDataView);
1395 }
1396
HWTEST_F_L0(JSNApiTests,ByteLength002)1397 HWTEST_F_L0(JSNApiTests, ByteLength002)
1398 {
1399 LocalScope scope(vm_);
1400 const int32_t length = 4; // define array length
1401 Local<ArrayBufferRef> array = ArrayBufferRef::New(vm_, length);
1402 int32_t arrayLen = array->ByteLength(vm_);
1403 EXPECT_EQ(length, arrayLen);
1404 }
1405
HWTEST_F_L0(JSNApiTests,SetData)1406 HWTEST_F_L0(JSNApiTests, SetData)
1407 {
1408 LocalScope scope(vm_);
1409 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
1410 struct Data {
1411 int32_t length;
1412 };
1413 const int32_t length = 15;
1414 Data *data = new Data();
1415 data->length = length;
1416 functioncallback->SetData(vm_, data);
1417 }
1418
HWTEST_F_L0(JSNApiTests,GetData)1419 HWTEST_F_L0(JSNApiTests, GetData)
1420 {
1421 LocalScope scope(vm_);
1422 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
1423 functioncallback->GetData(vm_);
1424 }
1425
HWTEST_F_L0(JSNApiTests,GetData002)1426 HWTEST_F_L0(JSNApiTests, GetData002)
1427 {
1428 LocalScope scope(vm_);
1429 int32_t argvLength = 10;
1430 auto ecmaRuntimeCallInfo =
1431 TestHelper::CreateEcmaRuntimeCallInfo(vm_->GetJSThread(), JSTaggedValue::Undefined(), argvLength);
1432 JsiRuntimeCallInfo *jsiRuntimeCallInfo = reinterpret_cast<JsiRuntimeCallInfo *>(ecmaRuntimeCallInfo);
1433 jsiRuntimeCallInfo->GetData();
1434 }
1435
HWTEST_F_L0(JSNApiTests,SetStopPreLoadSoCallback)1436 HWTEST_F_L0(JSNApiTests, SetStopPreLoadSoCallback)
1437 {
1438 auto callback = []()->void {
1439 LOG_FULL(INFO) << "Call stopPreLoadSoCallback";
1440 };
1441 JSNApi::SetStopPreLoadSoCallback(vm_, callback);
1442 auto stopPreLoadCallbacks = vm_->GetStopPreLoadCallbacks();
1443 EXPECT_EQ(stopPreLoadCallbacks.size(), 1);
1444 vm_->StopPreLoadSoOrAbc();
1445
1446 stopPreLoadCallbacks = vm_->GetStopPreLoadCallbacks();
1447 EXPECT_EQ(stopPreLoadCallbacks.size(), 0);
1448 }
1449
HWTEST_F_L0(JSNApiTests,UpdatePkgContextInfoList)1450 HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoList)
1451 {
1452 std::map<std::string, std::vector<std::vector<std::string>>> pkgList;
1453 std::vector<std::string> entryList = {
1454 "entry",
1455 "packageName", "entry",
1456 "bundleName", "",
1457 "moduleName", "",
1458 "version", "",
1459 "entryPath", "src/main/",
1460 "isSO", "false"
1461 };
1462 pkgList["entry"] = {entryList};
1463 JSNApi::SetpkgContextInfoList(vm_, pkgList);
1464
1465 std::map<std::string, std::vector<std::vector<std::string>>> newPkgList;
1466 std::vector<std::string> hspList = {
1467 "hsp",
1468 "packageName", "hsp",
1469 "bundleName", "",
1470 "moduleName", "",
1471 "version", "1.1.0",
1472 "entryPath", "Index.ets",
1473 "isSO", "false"
1474 };
1475 newPkgList["hsp"] = {hspList};
1476 JSNApi::UpdatePkgContextInfoList(vm_, newPkgList);
1477
1478 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();
1479 EXPECT_EQ(vmPkgList.size(), 2);
1480 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);
1481 EXPECT_EQ(vmPkgList["hsp"].size(), 1);
1482 EXPECT_EQ(vmPkgList["hsp"]["hsp"].size(), 12);
1483 }
1484
HWTEST_F_L0(JSNApiTests,UpdatePkgNameList)1485 HWTEST_F_L0(JSNApiTests, UpdatePkgNameList)
1486 {
1487 std::map<std::string, std::string> pkgNameList;
1488 pkgNameList["moduleName1"] = "pkgName1";
1489 JSNApi::SetPkgNameList(vm_, pkgNameList);
1490
1491 std::map<std::string, std::string> newPkgNameList;
1492 newPkgNameList["moduleName2"] = "pkgName2";
1493 JSNApi::UpdatePkgNameList(vm_, newPkgNameList);
1494
1495 CMap<CString, CString> vmPkgNameList = vm_->GetPkgNameList();
1496 EXPECT_EQ(vmPkgNameList.size(), 2);
1497 EXPECT_EQ(vmPkgNameList["moduleName1"], "pkgName1");
1498 EXPECT_EQ(vmPkgNameList["moduleName2"], "pkgName2");
1499 }
1500
HWTEST_F_L0(JSNApiTests,UpdatePkgAliasList)1501 HWTEST_F_L0(JSNApiTests, UpdatePkgAliasList)
1502 {
1503 std::map<std::string, std::string> aliasNameList;
1504 aliasNameList["aliasName1"] = "pkgName1";
1505 JSNApi::SetPkgAliasList(vm_, aliasNameList);
1506
1507 std::map<std::string, std::string> newAliasNameList;
1508 newAliasNameList["aliasName2"] = "pkgName2";
1509 JSNApi::UpdatePkgAliasList(vm_, newAliasNameList);
1510
1511 CMap<CString, CString> vmAliasNameList = vm_->GetPkgAliasList();
1512 EXPECT_EQ(vmAliasNameList.size(), 2);
1513 EXPECT_EQ(vmAliasNameList["aliasName1"], "pkgName1");
1514 EXPECT_EQ(vmAliasNameList["aliasName2"], "pkgName2");
1515 }
1516
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest001)1517 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest001)
1518 {
1519 LocalScope scope(vm_);
1520 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1521 Local<ArrayRef> array = ArrayRef::New(vm_, ARRAY_LENGTH);
1522 Local<JSValueRef> value(array);
1523 bool isJSArray = value->IsJSArray(vm_);
1524 ASSERT_EQ(isJSArray, true);
1525
1526 bool isPendingException = true;
1527 bool isArrayOrSharedArray = false;
1528 uint32_t arrayLength = 0;
1529 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1530 ASSERT_EQ(isPendingException, false);
1531 ASSERT_EQ(isArrayOrSharedArray, true);
1532 ASSERT_EQ(arrayLength, ARRAY_LENGTH);
1533 }
1534
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest002)1535 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest002)
1536 {
1537 LocalScope scope(vm_);
1538 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1539 Local<SendableArrayRef> sArray = SendableArrayRef::New(vm_, ARRAY_LENGTH);
1540 Local<JSValueRef> value(sArray);
1541 bool isSArray = value->IsSharedArray(vm_);
1542 ASSERT_EQ(isSArray, true);
1543
1544 bool isPendingException = true;
1545 bool isArrayOrSharedArray = false;
1546 uint32_t arrayLength = 0;
1547 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1548 ASSERT_EQ(isPendingException, false);
1549 ASSERT_EQ(isArrayOrSharedArray, true);
1550 ASSERT_EQ(arrayLength, ARRAY_LENGTH);
1551 }
1552
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest003)1553 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest003)
1554 {
1555 LocalScope scope(vm_);
1556 Local<ObjectRef> object = ObjectRef::New(vm_);
1557 Local<JSValueRef> value(object);
1558 bool isObject = value->IsObject(vm_);
1559 ASSERT_EQ(isObject, true);
1560
1561 bool isPendingException = true;
1562 bool isArrayOrSharedArray = false;
1563 const uint32_t INIT_VALUE = 10; // 10 means a randon initial value
1564 uint32_t arrayLength = INIT_VALUE;
1565 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1566 ASSERT_EQ(isPendingException, false);
1567 ASSERT_EQ(isArrayOrSharedArray, false);
1568 ASSERT_EQ(arrayLength, INIT_VALUE);
1569 }
1570
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest004)1571 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest004)
1572 {
1573 LocalScope scope(vm_);
1574 // create array
1575 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1576 Local<ArrayRef> array = ArrayRef::New(vm_, ARRAY_LENGTH);
1577 Local<JSValueRef> value(array);
1578 bool isJSArray = value->IsJSArray(vm_);
1579 ASSERT_EQ(isJSArray, true);
1580
1581 // throw error in thread
1582 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1583 ASSERT_EQ(error->IsError(vm_), true);
1584 JSNApi::ThrowException(vm_, error);
1585 JSThread *thread = vm_->GetJSThread();
1586 ASSERT_EQ(thread->HasPendingException(), true);
1587
1588 // test TryGetArrayLength
1589 bool isPendingException = false;
1590 bool isArrayOrSharedArray = false;
1591 uint32_t arrayLength = ARRAY_LENGTH;
1592 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1593 ASSERT_EQ(isPendingException, true);
1594 ASSERT_EQ(isArrayOrSharedArray, true);
1595 ASSERT_EQ(arrayLength, 0);
1596
1597 // clear exception
1598 JSNApi::GetAndClearUncaughtException(vm_);
1599 ASSERT_EQ(thread->HasPendingException(), false);
1600 }
1601
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest005)1602 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest005)
1603 {
1604 LocalScope scope(vm_);
1605 // create array
1606 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1607 Local<SendableArrayRef> sArray = SendableArrayRef::New(vm_, ARRAY_LENGTH);
1608 Local<JSValueRef> value(sArray);
1609 bool isSArray = value->IsSharedArray(vm_);
1610 ASSERT_EQ(isSArray, true);
1611
1612 // throw error in thread
1613 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1614 ASSERT_EQ(error->IsError(vm_), true);
1615 JSNApi::ThrowException(vm_, error);
1616 JSThread *thread = vm_->GetJSThread();
1617 ASSERT_EQ(thread->HasPendingException(), true);
1618
1619 // test TryGetArrayLength
1620 bool isPendingException = false;
1621 bool isArrayOrSharedArray = false;
1622 uint32_t arrayLength = ARRAY_LENGTH;
1623 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1624 ASSERT_EQ(isPendingException, true);
1625 ASSERT_EQ(isArrayOrSharedArray, true);
1626 ASSERT_EQ(arrayLength, 0);
1627
1628 // clear exception
1629 JSNApi::GetAndClearUncaughtException(vm_);
1630 ASSERT_EQ(thread->HasPendingException(), false);
1631 }
1632
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest006)1633 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest006)
1634 {
1635 LocalScope scope(vm_);
1636 Local<ObjectRef> object = ObjectRef::New(vm_);
1637 Local<JSValueRef> value(object);
1638 bool isObject = value->IsObject(vm_);
1639 ASSERT_EQ(isObject, true);
1640
1641 // throw error in thread
1642 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1643 ASSERT_EQ(error->IsError(vm_), true);
1644 JSNApi::ThrowException(vm_, error);
1645 JSThread *thread = vm_->GetJSThread();
1646 ASSERT_EQ(thread->HasPendingException(), true);
1647
1648 // test TryGetArrayLength
1649 bool isPendingException = false;
1650 bool isArrayOrSharedArray = true;
1651 const uint32_t INIT_VALUE = 10; // 10 means a randon initial value
1652 uint32_t arrayLength = INIT_VALUE;
1653 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1654 ASSERT_EQ(isPendingException, true);
1655 ASSERT_EQ(isArrayOrSharedArray, false);
1656 ASSERT_EQ(arrayLength, INIT_VALUE);
1657
1658 // clear exception
1659 JSNApi::GetAndClearUncaughtException(vm_);
1660 ASSERT_EQ(thread->HasPendingException(), false);
1661 }
1662
1663 /**
1664 * @tc.number: ffi_interface_api_147
1665 * @tc.name: UpdateStackInfo
1666 * @tc.desc: Used to verify whether the function of update stack info was successful.
1667 * @tc.type: FUNC
1668 * @tc.require: parameter
1669 */
HWTEST_F_L0(JSNApiTests,UpdateStackInfo)1670 HWTEST_F_L0(JSNApiTests, UpdateStackInfo)
1671 {
1672 LocalScope scope(vm_);
1673 StackInfo stackInfo = { 0x10000, 0 };
1674 uint64_t currentStackLimit = vm_->GetJSThread()->GetStackLimit();
1675 JSNApi::UpdateStackInfo(vm_, &stackInfo, 0);
1676 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), 0x10000);
1677 JSNApi::UpdateStackInfo(vm_, &stackInfo, 1);
1678 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), currentStackLimit);
1679 JSNApi::UpdateStackInfo(vm_, nullptr, 0);
1680 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), currentStackLimit);
1681 }
1682 } // namespace panda::test
1683