• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace panda::test {
67 using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction;
68 using PGOProfilerManager = panda::ecmascript::pgo::PGOProfilerManager;
69 using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
70 class JSNApiTests : public testing::Test {
71 public:
SetUpTestCase()72     static void SetUpTestCase()
73     {
74         GTEST_LOG_(INFO) << "SetUpTestCase";
75     }
76 
TearDownTestCase()77     static void TearDownTestCase()
78     {
79         GTEST_LOG_(INFO) << "TearDownCase";
80     }
81 
SetUp()82     void SetUp() override
83     {
84         RuntimeOption option;
85         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
86         vm_ = JSNApi::CreateJSVM(option);
87         ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
88         thread_ = vm_->GetJSThread();
89         vm_->SetEnableForceGC(true);
90         thread_->ManagedCodeBegin();
91     }
92 
TearDown()93     void TearDown() override
94     {
95         thread_->ManagedCodeEnd();
96         vm_->SetEnableForceGC(false);
97         JSNApi::DestroyJSVM(vm_);
98     }
99 
TestNumberRef(T val,TaggedType expected)100     template <typename T> void TestNumberRef(T val, TaggedType expected)
101     {
102         LocalScope scope(vm_);
103         Local<NumberRef> obj = NumberRef::New(vm_, val);
104         ASSERT_TRUE(obj->IsNumber());
105         JSTaggedType res = JSNApiHelper::ToJSTaggedValue(*obj).GetRawData();
106         ASSERT_EQ(res, expected);
107         if constexpr (std::is_floating_point_v<T>) {
108             if (std::isnan(val)) {
109                 ASSERT_TRUE(std::isnan(obj->Value()));
110             } else {
111                 ASSERT_EQ(obj->Value(), val);
112             }
113         } else if constexpr (sizeof(T) >= sizeof(int32_t)) {
114             ASSERT_EQ(obj->IntegerValue(vm_), val);
115         } else if constexpr (std::is_signed_v<T>) {
116             ASSERT_EQ(obj->Int32Value(vm_), val);
117         } else {
118             ASSERT_EQ(obj->Uint32Value(vm_), val);
119         }
120     }
121 
ConvertDouble(double val)122     TaggedType ConvertDouble(double val)
123     {
124         return base::bit_cast<JSTaggedType>(val) + JSTaggedValue::DOUBLE_ENCODE_OFFSET;
125     }
126 
127 protected:
128     void RegisterStringCacheTable();
129 
130     JSThread *thread_ = nullptr;
131     EcmaVM *vm_ = nullptr;
132     bool isStringCacheTableCreated_ = false;
133 };
134 
RegisterStringCacheTable()135 void JSNApiTests::RegisterStringCacheTable()
136 {
137     constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
138     auto res = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
139     if (isStringCacheTableCreated_) {
140         ASSERT_FALSE(res);
141     } else {
142         ASSERT_TRUE(res);
143     }
144 }
145 
FunctionCallback(JsiRuntimeCallInfo * info)146 Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info)
147 {
148     EscapeLocalScope scope(info->GetVM());
149     return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
150 }
151 
WeakRefCallback(EcmaVM * vm)152 void WeakRefCallback(EcmaVM *vm)
153 {
154     LocalScope scope(vm);
155     Local<ObjectRef> object = ObjectRef::New(vm);
156     Global<ObjectRef> globalObject(vm, object);
157     globalObject.SetWeak();
158     Local<ObjectRef> object1 = ObjectRef::New(vm);
159     Global<ObjectRef> globalObject1(vm, object1);
160     globalObject1.SetWeak();
161     vm->CollectGarbage(TriggerGCType::YOUNG_GC);
162     vm->CollectGarbage(TriggerGCType::OLD_GC);
163     globalObject.FreeGlobalHandleAddr();
164 }
165 
ThreadCheck(const EcmaVM * vm)166 void ThreadCheck(const EcmaVM *vm)
167 {
168     EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId());
169 }
170 
CheckReject(JsiRuntimeCallInfo * info)171 void CheckReject(JsiRuntimeCallInfo *info)
172 {
173     ASSERT_EQ(info->GetArgsNumber(), 1U);
174     Local<JSValueRef> reason = info->GetCallArgRef(0);
175     ASSERT_TRUE(reason->IsString(info->GetVM()));
176     ASSERT_EQ(Local<StringRef>(reason)->ToString(info->GetVM()), "Reject");
177 }
178 
RejectCallback(JsiRuntimeCallInfo * info)179 Local<JSValueRef> RejectCallback(JsiRuntimeCallInfo *info)
180 {
181     LocalScope scope(info->GetVM());
182     CheckReject(info);
183     return JSValueRef::Undefined(info->GetVM());
184 }
185 
186 /**
187  * @tc.number: ffi_interface_api_105
188  * @tc.name: JSValueRef_IsGeneratorObject
189  * @tc.desc: Determine if it is a Generator generator object
190  * @tc.type: FUNC
191  * @tc.require:  parameter
192  */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsGeneratorObject)193 HWTEST_F_L0(JSNApiTests, JSValueRef_IsGeneratorObject)
194 {
195     LocalScope scope(vm_);
196     ObjectFactory *factory = vm_->GetFactory();
197     auto env = vm_->GetGlobalEnv();
198     JSHandle<JSTaggedValue> genFunc = env->GetGeneratorFunctionFunction();
199     JSHandle<JSGeneratorObject> genObjHandleVal = factory->NewJSGeneratorObject(genFunc);
200     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
201     JSHandle<JSFunction> generatorFunc = JSHandle<JSFunction>::Cast(factory->NewJSObject(hclass));
202     JSFunction::InitializeJSFunction(thread_, generatorFunc, FunctionKind::GENERATOR_FUNCTION);
203     JSHandle<GeneratorContext> generatorContext = factory->NewGeneratorContext();
204     generatorContext->SetMethod(thread_, generatorFunc.GetTaggedValue());
205     JSHandle<JSTaggedValue> generatorContextVal = JSHandle<JSTaggedValue>::Cast(generatorContext);
206     genObjHandleVal->SetGeneratorContext(thread_, generatorContextVal.GetTaggedValue());
207     JSHandle<JSTaggedValue> genObjTagHandleVal = JSHandle<JSTaggedValue>::Cast(genObjHandleVal);
208     Local<JSValueRef> genObjectRef = JSNApiHelper::ToLocal<GeneratorObjectRef>(genObjTagHandleVal);
209     ASSERT_TRUE(genObjectRef->IsGeneratorObject(vm_));
210 }
211 
JSObjectTestCreate(JSThread * thread)212 static JSFunction *JSObjectTestCreate(JSThread *thread)
213 {
214     EcmaVM *ecmaVM = thread->GetEcmaVM();
215     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
216     return globalEnv->GetObjectFunction().GetObject<JSFunction>();
217 }
218 
219 /**
220  * @tc.number: ffi_interface_api_106
221  * @tc.name: JSValueRef_IsProxy
222  * @tc.desc: Determine if it is the type of proxy
223  * @tc.type: FUNC
224  * @tc.require:  parameter
225  */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsProxy)226 HWTEST_F_L0(JSNApiTests, JSValueRef_IsProxy)
227 {
228     LocalScope scope(vm_);
229     JSHandle<JSTaggedValue> hclass(thread_, JSObjectTestCreate(thread_));
230     JSHandle<JSTaggedValue> targetHandle(
231         thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
232 
233     JSHandle<JSTaggedValue> key(thread_->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
234     JSHandle<JSTaggedValue> value(thread_, JSTaggedValue(1));
235     JSObject::SetProperty(thread_, targetHandle, key, value);
236     EXPECT_EQ(JSObject::GetProperty(thread_, targetHandle, key).GetValue()->GetInt(), 1);
237 
238     JSHandle<JSTaggedValue> handlerHandle(
239         thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
240     EXPECT_TRUE(handlerHandle->IsECMAObject());
241 
242     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread_, targetHandle, handlerHandle);
243     EXPECT_TRUE(*proxyHandle != nullptr);
244 
245     EXPECT_EQ(JSProxy::GetProperty(thread_, proxyHandle, key).GetValue()->GetInt(), 1);
246     PropertyDescriptor desc(thread_);
247     JSProxy::GetOwnProperty(thread_, proxyHandle, key, desc);
248     EXPECT_EQ(desc.GetValue()->GetInt(), 1);
249     Local<JSValueRef> proxy = JSNApiHelper::ToLocal<JSProxy>(JSHandle<JSTaggedValue>(proxyHandle));
250     ASSERT_TRUE(proxy->IsProxy(vm_));
251 }
252 
253 /**
254  * @tc.number: ffi_interface_api_107
255  * @tc.name: BufferRef_New_ByteLength
256  * @tc.desc:
257  * New:Create a buffer and specify the length size
258  * ByteLength:Returns the length of the buffer
259  * @tc.type: FUNC
260  * @tc.require:  parameter
261  */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength)262 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength)
263 {
264     LocalScope scope(vm_);
265     int32_t length = 10;
266     Local<BufferRef> buffer = BufferRef::New(vm_, length);
267     ASSERT_TRUE(buffer->IsBuffer(vm_));
268     EXPECT_EQ(buffer->ByteLength(vm_), length);
269 }
270 
271 /**
272  * @tc.number: ffi_interface_api_108
273  * @tc.name: BufferRef_New_ByteLength_GetBuffer
274  * @tc.desc:
275  * New:Create a buffer and specify the length size
276  * ByteLength:Returns the length of the buffer
277  * GetBuffer:Return buffer pointer
278  * @tc.type: FUNC
279  * @tc.require:  parameter
280  */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength_GetBuffer)281 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength_GetBuffer)
282 {
283     LocalScope scope(vm_);
284     int32_t length = 10;
285     Local<BufferRef> buffer = BufferRef::New(vm_, length);
286     ASSERT_TRUE(buffer->IsBuffer(vm_));
287     EXPECT_EQ(buffer->ByteLength(vm_), 10U);
288     ASSERT_NE(buffer->GetBuffer(vm_), nullptr);
289 }
290 
291 /**
292  * @tc.number: ffi_interface_api_109
293  * @tc.name: BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback
294  * @tc.desc:
295  * BufferToStringCallback:Implement callback when calling ToString (vm) mode in buffer
296  * @tc.type: FUNC
297  * @tc.require:  parameter
298  */
HWTEST_F_L0(JSNApiTests,BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)299 HWTEST_F_L0(JSNApiTests, BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)
300 {
301     LocalScope scope(vm_);
302     static bool isFree = false;
303     struct Data {
304         int32_t length;
305     };
306     const int32_t length = 15;
307     NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
308         delete[] reinterpret_cast<uint8_t *>(buffer);
309         Data *currentData = reinterpret_cast<Data *>(data);
310         delete currentData;
311         isFree = true;
312     };
313     isFree = false;
314     uint8_t *buffer = new uint8_t[length]();
315     Data *data = new Data();
316     data->length = length;
317     Local<BufferRef> bufferRef = BufferRef::New(vm_, buffer, length, deleter, data);
318     ASSERT_TRUE(bufferRef->IsBuffer(vm_));
319     ASSERT_TRUE(bufferRef->IsBuffer(vm_));
320     EXPECT_EQ(bufferRef->ByteLength(vm_), 15U);
321     Local<StringRef> bufferStr = bufferRef->ToString(vm_);
322     ASSERT_TRUE(bufferStr->IsString(vm_));
323 }
324 
325 /**
326  * @tc.number: ffi_interface_api_110
327  * @tc.name: LocalScope_LocalScope
328  * @tc.desc: Build Escape LocalScope sub Vm scope
329  * @tc.type: FUNC
330  * @tc.require:  parameter
331  */
HWTEST_F_L0(JSNApiTests,LocalScope_LocalScope)332 HWTEST_F_L0(JSNApiTests, LocalScope_LocalScope)
333 {
334     EscapeLocalScope scope(vm_);
335     LocalScope *perScope = nullptr;
336     perScope = &scope;
337     ASSERT_TRUE(perScope != nullptr);
338 }
339 
340 /**
341  * @tc.number: ffi_interface_api_111
342  * @tc.name: JSNApi_CreateJSContext_SwitchCurrentContext_DestroyJSContext
343  * @tc.desc:
344  * CreateJSContext:Create Context Object Pointer
345  * SwitchCurrentContext:Record Update Context Object
346  * DestroyJSContext:Delete Context Object
347  * @tc.type: FUNC
348  * @tc.require:  parameter
349  */
HWTEST_F_L0(JSNApiTests,JSNApi_SwitchCurrentContext_DestroyJSContext)350 HWTEST_F_L0(JSNApiTests, JSNApi_SwitchCurrentContext_DestroyJSContext)
351 {
352     LocalScope scope(vm_);
353     EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 1);
354     EcmaContext *context = JSNApi::CreateJSContext(vm_);
355     GTEST_LOG_(WARNING) << "context test =" << context;
356     EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 2);
357     EcmaContext *context1 = JSNApi::CreateJSContext(vm_);
358     EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 3);
359     JSNApi::SwitchCurrentContext(vm_, context1);
360     EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 3);
361     JSNApi::DestroyJSContext(vm_, context1);
362     EXPECT_EQ(vm_->GetJSThread()->GetEcmaContexts().size(), 2);
363 }
364 
365 /**
366  * @tc.number: ffi_interface_api_112
367  * @tc.name: JSNApi_CreateJSVM_DestroyJSVM
368  * @tc.desc: Create/delete JSVM
369  * @tc.type: FUNC
370  * @tc.require:  parameter
371  */
HWTEST_F_L0(JSNApiTests,JSNApi_CreateJSVM_DestroyJSVM)372 HWTEST_F_L0(JSNApiTests, JSNApi_CreateJSVM_DestroyJSVM)
373 {
374     LocalScope scope(vm_);
375     std::thread t1([&](){
376         EcmaVM *vm1_ = nullptr;
377         RuntimeOption option;
378         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
379         vm1_ = JSNApi::CreateJSVM(option);
380         ASSERT_TRUE(vm1_ != nullptr) << "Cannot create Runtime";
381         vm1_->SetEnableForceGC(true);
382         vm1_->SetEnableForceGC(false);
383         JSNApi::DestroyJSVM(vm1_);
384     });
385     {
386         ThreadSuspensionScope suspensionScope(thread_);
387         t1.join();
388     }
389 }
390 
391 /**
392  * @tc.number: ffi_interface_api_114
393  * @tc.name: JSNApi_GetUncaughtException
394  * @tc.desc: Get uncaught exceptions
395  * @tc.type: FUNC
396  * @tc.require:  parameter
397  */
HWTEST_F_L0(JSNApiTests,JSNApi_GetUncaughtException)398 HWTEST_F_L0(JSNApiTests, JSNApi_GetUncaughtException)
399 {
400     LocalScope scope(vm_);
401     Local<ObjectRef> excep = JSNApi::GetUncaughtException(vm_);
402     ASSERT_TRUE(excep.IsNull()) << "CreateInstance occur Exception";
403 }
404 
FuncRefNewCallbackForTest(JsiRuntimeCallInfo * info)405 Local<JSValueRef> FuncRefNewCallbackForTest(JsiRuntimeCallInfo *info)
406 {
407     GTEST_LOG_(INFO) << "runing FuncRefNewCallbackForTest";
408     EscapeLocalScope scope(info->GetVM());
409     return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
410 }
411 
412 /**
413  * @tc.number: ffi_interface_api_115
414  * @tc.name: ObjectRef_SetAccessorProperty
415  * @tc.desc:
416  * SetAccessorProperty:Set AccessorPro Properties
417  * GetVM:Obtain environment information for runtime calls
418  * LocalScope:Build Vm Scope
419  * @tc.type: FUNC
420  * @tc.require:  parameter
421  */
HWTEST_F_L0(JSNApiTests,ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)422 HWTEST_F_L0(JSNApiTests, ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)
423 {
424     LocalScope scope(vm_);
425     Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
426     FunctionForRef nativeFunc = FuncRefNewCallbackForTest;
427     Local<FunctionRef> getter = FunctionRef::New(vm_, nativeFunc);
428     Local<FunctionRef> setter = FunctionRef::New(vm_, nativeFunc);
429     Local<ObjectRef> object = ObjectRef::New(vm_);
430     ASSERT_TRUE(object->SetAccessorProperty(vm_, key, getter, setter));
431 }
432 
433 /*
434  * @tc.number: ffi_interface_api_116
435  * @tc.name: JSNApi_IsBoolean
436  * @tc.desc: Judge  whether obj is a boolean type
437  * @tc.type: FUNC
438  * @tc.require:  parameter
439  */
HWTEST_F_L0(JSNApiTests,IsBoolean)440 HWTEST_F_L0(JSNApiTests, IsBoolean)
441 {
442     LocalScope scope(vm_);
443     char16_t utf16[] = u"This is a char16 array";
444     int size = sizeof(utf16);
445     Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
446     ASSERT_FALSE(obj->IsBoolean());
447 }
448 
449 /*
450  * @tc.number: ffi_interface_api_117
451  * @tc.name: JSNApi_IsNULL
452  * @tc.desc: Judge  whether obj is a null type
453  * @tc.type: FUNC
454  * @tc.require:  parameter
455  */
HWTEST_F_L0(JSNApiTests,IsNULL)456 HWTEST_F_L0(JSNApiTests, IsNULL)
457 {
458     LocalScope scope(vm_);
459     char16_t utf16[] = u"This is a char16 array";
460     int size = sizeof(utf16);
461     Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
462     ASSERT_FALSE(obj->IsNull());
463 }
464 
465 /*
466  * @tc.number: ffi_interface_api_118
467  * @tc.name: JSNApi_GetTime
468  * @tc.desc: This function is to catch time
469  * @tc.type: FUNC
470  * @tc.require:  parameter
471  */
HWTEST_F_L0(JSNApiTests,GetTime)472 HWTEST_F_L0(JSNApiTests, GetTime)
473 {
474     LocalScope scope(vm_);
475     const double time = 14.29;
476     Local<DateRef> date = DateRef::New(vm_, time);
477     ASSERT_EQ(date->GetTime(vm_), time);
478 }
479 
480 /*
481  * @tc.number: ffi_interface_api_119
482  * @tc.name: JSNApi_IsDetach
483  * @tc.desc: Judge whether arraybuffer is detached
484  * @tc.type: FUNC
485  * @tc.require:  parameter
486  */
HWTEST_F_L0(JSNApiTests,IsDetach)487 HWTEST_F_L0(JSNApiTests, IsDetach)
488 {
489     LocalScope scope(vm_);
490     const int32_t length = 33;
491     Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
492     ASSERT_FALSE(arraybuffer->IsDetach(vm_));
493 }
494 
495 /*
496  * @tc.number: ffi_interface_api_120
497  * @tc.name: JSNApi_Detach
498  * @tc.desc: This function is to detach arraybuffer
499  * @tc.type: FUNC
500  * @tc.require:  parameter
501  */
HWTEST_F_L0(JSNApiTests,Detach)502 HWTEST_F_L0(JSNApiTests, Detach)
503 {
504     LocalScope scope(vm_);
505     const int32_t length = 33;
506     Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
507     arraybuffer->Detach(vm_);
508 }
509 
510 /*
511  * @tc.number: ffi_interface_api_121
512  * @tc.name: JSNApi_New1
513  * @tc.desc:  create a obj that is a arraybuffer type
514  * @tc.type: FUNC
515  * @tc.require:  parameter
516  */
HWTEST_F_L0(JSNApiTests,New1)517 HWTEST_F_L0(JSNApiTests, New1)
518 {
519     LocalScope scope(vm_);
520     const int32_t length = 33;
521     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
522     ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
523     ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
524     ASSERT_NE(arrayBuffer->GetBuffer(vm_), nullptr);
525 }
526 
527 /*
528  * @tc.number: ffi_interface_api_122
529  * @tc.name: JSNApi_New1
530  * @tc.desc:  create a obj that is a arraybuffer type
531  * @tc.type: FUNC
532  * @tc.require:  parameter
533  */
HWTEST_F_L0(JSNApiTests,New2)534 HWTEST_F_L0(JSNApiTests, New2)
535 {
536     static bool isFree = false;
537     struct Data {
538         int32_t length;
539     };
540     const int32_t length = 15;
541     Data *data = new Data();
542     data->length = length;
543     NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
544         delete[] reinterpret_cast<uint8_t *>(buffer);
545         Data *currentData = reinterpret_cast<Data *>(data);
546         ASSERT_EQ(currentData->length, 15); // 5 : size of arguments
547         delete currentData;
548         isFree = true;
549     };
550     {
551         LocalScope scope(vm_);
552         uint8_t *buffer = new uint8_t[length]();
553         Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
554         ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
555         ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
556         ASSERT_EQ(arrayBuffer->GetBuffer(vm_), buffer);
557     }
558 }
559 
560 /*
561  * @tc.number: ffi_interface_api_123
562  * @tc.name: JSNApi_Bytelength
563  * @tc.desc:   capture bytelength of arraybuffer
564  * @tc.type: FUNC
565  * @tc.require:  parameter
566  */
HWTEST_F_L0(JSNApiTests,Bytelength)567 HWTEST_F_L0(JSNApiTests, Bytelength)
568 {
569     LocalScope scope(vm_);
570     const int32_t length = 33;
571     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
572     ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
573 }
574 
575 /*
576  * @tc.number: ffi_interface_api_124
577  * @tc.name: JSNApi_GetBuffer
578  * @tc.desc:  capture buffer of arraybuffer
579  * @tc.type: FUNC
580  * @tc.require:  parameter
581  */
HWTEST_F_L0(JSNApiTests,GetBuffer)582 HWTEST_F_L0(JSNApiTests, GetBuffer)
583 {
584     LocalScope scope(vm_);
585     const int32_t length = 33;
586     Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
587     ASSERT_NE(arraybuffer->GetBuffer(vm_), nullptr);
588 }
589 
590 /*
591  * @tc.number: ffi_interface_api_125
592  * @tc.name: JSNApi_Is32Arraytest
593  * @tc.desc:  judge  whether obj is a int32array type,
594  * judge  whether obj is a uint32array type,
595  * judge  whether obj is a float32array type,
596  * judge  whether obj is a float64array type,
597  * @tc.type: FUNC
598  * @tc.require:  parameter
599  */
HWTEST_F_L0(JSNApiTests,Is32Arraytest)600 HWTEST_F_L0(JSNApiTests, Is32Arraytest)
601 {
602     LocalScope scope(vm_);
603     char16_t utf16[] = u"This is a char16 array";
604     int size = sizeof(utf16);
605     Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
606     ASSERT_FALSE(obj->IsInt32Array(vm_));
607     ASSERT_FALSE(obj->IsUint32Array(vm_));
608     ASSERT_FALSE(obj->IsFloat32Array(vm_));
609     ASSERT_FALSE(obj->IsFloat64Array(vm_));
610 }
611 
612 /*
613  * @tc.number: ffi_interface_api_126
614  * @tc.name: JSNApi_SynchronizVMInfo
615  * @tc.desc:  capture  synchronous info of vm
616  * @tc.type: FUNC
617  * @tc.require:  parameter
618  */
HWTEST_F_L0(JSNApiTests,SynchronizVMInfo)619 HWTEST_F_L0(JSNApiTests, SynchronizVMInfo)
620 {
621     LocalScope scope(vm_);
622     std::thread t1([&]() {
623         JSRuntimeOptions option;
624         EcmaVM *hostVM = JSNApi::CreateEcmaVM(option);
625         {
626             LocalScope scope2(hostVM);
627             JSNApi::SynchronizVMInfo(vm_, hostVM);
628         }
629         JSNApi::DestroyJSVM(hostVM);
630     });
631     {
632         ThreadSuspensionScope suspensionScope(thread_);
633         t1.join();
634     }
635 }
636 
637 /*
638  * @tc.number: ffi_interface_api_127
639  * @tc.name: JSNApi_IsProfiling
640  * @tc.desc:  judge whether vm is profiling
641  * @tc.type: FUNC
642  * @tc.require:  parameter
643  */
HWTEST_F_L0(JSNApiTests,IsProfiling)644 HWTEST_F_L0(JSNApiTests, IsProfiling)
645 {
646     LocalScope scope(vm_);
647     ASSERT_FALSE(JSNApi::IsProfiling(vm_));
648 }
649 
650 /*
651  * @tc.number: ffi_interface_api_128
652  * @tc.name: JSNApi_SetProfilerState
653  * @tc.desc:  This function is to set state of profiler
654  * @tc.type: FUNC
655  * @tc.require:  parameter
656  */
HWTEST_F_L0(JSNApiTests,SetProfilerState)657 HWTEST_F_L0(JSNApiTests, SetProfilerState)
658 {
659     bool value = true;
660     bool value2 = false;
661     LocalScope scope(vm_);
662     JSNApi::SetProfilerState(vm_, value);
663     JSNApi::SetProfilerState(vm_, value2);
664 }
665 
666 /*
667  * @tc.number: ffi_interface_api_129
668  * @tc.name: JSNApi_SetLoop
669  * @tc.desc:  This function is to set loop
670  * @tc.type: FUNC
671  * @tc.require:  parameter
672  */
HWTEST_F_L0(JSNApiTests,SetLoop)673 HWTEST_F_L0(JSNApiTests, SetLoop)
674 {
675     LocalScope scope(vm_);
676     void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
677     JSNApi::SetLoop(vm_, data);
678 }
679 
680 /*
681  * @tc.number: ffi_interface_api_130
682  * @tc.name: JSNApi_SetHostPromiseRejectionTracker
683  * @tc.desc:  This function is to set host promise rejection about tracker
684  * @tc.type: FUNC
685  * @tc.require:  parameter
686  */
HWTEST_F_L0(JSNApiTests,SetHostPromiseRejectionTracker)687 HWTEST_F_L0(JSNApiTests, SetHostPromiseRejectionTracker)
688 {
689     LocalScope scope(vm_);
690     void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
691     void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
692     JSNApi::SetHostPromiseRejectionTracker(vm_, cb, data);
693 }
694 
695 /*
696  * @tc.number: ffi_interface_api_131
697  * @tc.name: JSNApi_SetHostResolveBufferTracker
698  * @tc.desc:   This function is to set host resolve buffer about tracker
699  * @tc.type: FUNC
700  * @tc.require:  parameter
701  */
HWTEST_F_L0(JSNApiTests,SetHostResolveBufferTracker)702 HWTEST_F_L0(JSNApiTests, SetHostResolveBufferTracker)
703 {
704     LocalScope scope(vm_);
705     JSNApi::SetHostResolveBufferTracker(vm_,
706         [&](std::string, uint8_t **, size_t *, std::string &) -> bool { return true; });
707 }
708 
709 /*
710  * @tc.number: ffi_interface_api_132
711  * @tc.name: JSNApi_SetUnloadNativeModuleCallback
712  * @tc.desc:   This function is to set unload native module  about callback
713  * @tc.type: FUNC
714  * @tc.require:  parameter
715  */
HWTEST_F_L0(JSNApiTests,SetUnloadNativeModuleCallback)716 HWTEST_F_L0(JSNApiTests, SetUnloadNativeModuleCallback)
717 {
718     LocalScope scope(vm_);
719     JSNApi::SetUnloadNativeModuleCallback(vm_, [&](const std::string &) -> bool { return true; });
720 }
721 
722 /*
723  * @tc.number: ffi_interface_api_133
724  * @tc.name: JSNApi_SetNativePtrGetter
725  * @tc.desc:   This function is to set a native pointer about getter
726  * @tc.type: FUNC
727  * @tc.require:  parameter
728  */
HWTEST_F_L0(JSNApiTests,SetNativePtrGetter)729 HWTEST_F_L0(JSNApiTests, SetNativePtrGetter)
730 {
731     LocalScope scope(vm_);
732     void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
733     JSNApi::SetNativePtrGetter(vm_, cb);
734 }
735 
736 /*
737  * @tc.number: ffi_interface_api_134
738  * @tc.name: JSNApi_PreFork
739  * @tc.desc:  This function is to set prefork
740  * @tc.type: FUNC
741  * @tc.require:  parameter
742  */
HWTEST_F_L0(JSNApiTests,PreFork)743 HWTEST_F_L0(JSNApiTests, PreFork)
744 {
745     LocalScope scope(vm_);
746     JSNApi::PreFork(vm_);
747 }
748 
749 /*
750  * @tc.number: ffi_interface_api_135
751  * @tc.name: JSNApi_PostFork
752  * @tc.desc:  This function is to set postfork
753  * @tc.type: FUNC
754  * @tc.require:  parameter
755  */
HWTEST_F_L0(JSNApiTests,PostFork)756 HWTEST_F_L0(JSNApiTests, PostFork)
757 {
758     RuntimeOption option;
759     ecmascript::ThreadNativeScope nativeScope(vm_->GetJSThread());
760     LocalScope scope(vm_);
761     JSNApi::PreFork(vm_);
762     JSNApi::PostFork(vm_, option);
763 }
764 
765 
766 /*
767  * @tc.number: ffi_interface_api_136
768  * @tc.name: JSNApi_NewFromUtf8
769  * @tc.desc:  create a newfromutf8 object
770  * @tc.type: FUNC
771  * @tc.require:  parameter
772  */
HWTEST_F_L0(JSNApiTests,NewFromUtf8)773 HWTEST_F_L0(JSNApiTests, NewFromUtf8)
774 {
775     LocalScope scope(vm_);
776     char utf8[] = "hello world!";
777     int length = strlen(utf8);
778     Local<StringRef> result = StringRef::NewFromUtf8(vm_, utf8, length);
779     ASSERT_EQ(result->Utf8Length(vm_), length + 1);
780 }
781 
782 /*
783  * @tc.number: ffi_interface_api_137
784  * @tc.name: JSNApi_NewFromUtf16
785  * @tc.desc:  create a newfromutf16 object
786  * @tc.type: FUNC
787  * @tc.require:  parameter
788  */
HWTEST_F_L0(JSNApiTests,NewFromUtf16)789 HWTEST_F_L0(JSNApiTests, NewFromUtf16)
790 {
791     LocalScope scope(vm_);
792     char16_t utf16[] = u"This is a char16 array";
793     int length = sizeof(utf16);
794     Local<StringRef> result = StringRef::NewFromUtf16(vm_, utf16, length);
795     ASSERT_EQ(result->Length(vm_), length);
796 }
797 
798 /*
799  * @tc.number: ffi_interface_api_138
800  * @tc.name: JSNApi_GetNapiWrapperString
801  * @tc.desc:  This function is to get a napiwrapper string
802  * @tc.type: FUNC
803  * @tc.require:  parameter
804  */
HWTEST_F_L0(JSNApiTests,GetNapiWrapperString)805 HWTEST_F_L0(JSNApiTests, GetNapiWrapperString)
806 {
807     LocalScope scope(vm_);
808     Local<StringRef> result = StringRef::GetNapiWrapperString(vm_);
809     ASSERT_TRUE(result->IsString(vm_));
810 }
811 
812 /*
813  * @tc.number: ffi_interface_api_139
814  * @tc.name: JSNApi_JSExecutionScope
815  * @tc.desc:  This function is to construct a object of jsexecutionscope
816  * @tc.type: FUNC
817  * @tc.require:  parameter
818  */
HWTEST_F_L0(JSNApiTests,JSExecutionScope)819 HWTEST_F_L0(JSNApiTests, JSExecutionScope)
820 {
821     LocalScope scope(vm_);
822     JSExecutionScope jsexecutionScope(vm_);
823 }
824 
825 /*
826  * @tc.number: ffi_interface_api_140
827  * @tc.name: WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue
828  * @tc.desc:  This function is to set a weakmap and capture it's size ,
829  * key, value and total elements
830  * @tc.type: FUNC
831  * @tc.require:  parameter
832  */
HWTEST_F_L0(JSNApiTests,WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)833 HWTEST_F_L0(JSNApiTests, WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)
834 {
835     LocalScope scope(vm_);
836     JSThread *thread = vm_->GetJSThread();
837     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
838     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
839     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakMapFunction();
840     JSHandle<JSWeakMap> weakMap =
841         JSHandle<JSWeakMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
842     JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
843     weakMap->SetLinkedMap(thread, hashMap);
844     JSHandle<JSTaggedValue> weakMapTag = JSHandle<JSTaggedValue>::Cast(weakMap);
845 
846     Local<WeakMapRef> map = JSNApiHelper::ToLocal<WeakMapRef>(weakMapTag);
847     EXPECT_TRUE(map->IsWeakMap(vm_));
848     JSHandle<JSTaggedValue> value(factory->NewFromASCII("value"));
849     JSHandle<JSTaggedValue> key(factory->NewFromASCII("key"));
850     JSWeakMap::Set(thread, weakMap, key, value);
851     int32_t num = map->GetSize(vm_);
852     int32_t num1 = map->GetTotalElements(vm_);
853     ASSERT_EQ(num, 1);
854     ASSERT_EQ(num1, 1);
855     Local<JSValueRef> res1 = map->GetKey(vm_, 0);
856     ASSERT_EQ(res1->ToString(vm_)->ToString(vm_), "key");
857     Local<JSValueRef> res2 = map->GetValue(vm_, 0);
858     ASSERT_EQ(res2->ToString(vm_)->ToString(vm_), "value");
859 }
860 
861 /*
862  * @tc.number: ffi_interface_api_141
863  * @tc.name: JSNApi_ IsAGJA
864  * @tc.desc:  This function is to judge whether object is a argumentsobject or
865  * is a generatorfunction or is a asyncfunction
866  * @tc.type: FUNC
867  * @tc.require:  parameter
868  */
HWTEST_F_L0(JSNApiTests,IsAGJA)869 HWTEST_F_L0(JSNApiTests, IsAGJA)
870 {
871     LocalScope scope(vm_);
872     char16_t utf16[] = u"This is a char16 array";
873     int size = sizeof(utf16);
874     Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
875     ASSERT_FALSE(obj->IsArgumentsObject(vm_));
876     ASSERT_FALSE(obj->IsGeneratorFunction(vm_));
877     ASSERT_FALSE(obj->IsAsyncFunction(vm_));
878 }
879 
880 /**
881  * @tc.number: ffi_interface_api_143
882  * @tc.name: Int32Array
883  * @tc.desc: Catch exceptions correctly
884  * @tc.type: FUNC
885  * @tc.require:  parameter
886  */
HWTEST_F_L0(JSNApiTests,HasCaught)887 HWTEST_F_L0(JSNApiTests, HasCaught)
888 {
889     LocalScope scope(vm_);
890     Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
891     Local<JSValueRef> error = Exception::Error(vm_, message);
892     ASSERT_TRUE(error->IsError(vm_));
893     JSNApi::ThrowException(vm_, error);
894     TryCatch tryCatch(vm_);
895     ASSERT_TRUE(tryCatch.HasCaught());
896     vm_->GetJSThread()->ClearException();
897     ASSERT_FALSE(tryCatch.HasCaught());
898 }
899 
900 /**
901  * @tc.number: ffi_interface_api_144
902  * @tc.name: Int32Array
903  * @tc.desc: Rethrow the exception
904  * @tc.type: FUNC
905  * @tc.require:  parameter
906  */
HWTEST_F_L0(JSNApiTests,Rethrow)907 HWTEST_F_L0(JSNApiTests, Rethrow)
908 {
909     LocalScope scope(vm_);
910     TryCatch tryCatch(vm_);
911     tryCatch.Rethrow();
912     ASSERT_TRUE(tryCatch.getrethrow_());
913 }
914 
915 /**
916  * @tc.number: ffi_interface_api_145
917  * @tc.name: Int32Array
918  * @tc.desc: Clear caught exceptions
919  * @tc.type: FUNC
920  * @tc.require:  parameter
921  */
HWTEST_F_L0(JSNApiTests,GetAndClearException)922 HWTEST_F_L0(JSNApiTests, GetAndClearException)
923 {
924     LocalScope scope(vm_);
925     Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
926     Local<JSValueRef> error = Exception::Error(vm_, message);
927     ASSERT_TRUE(error->IsError(vm_));
928     JSNApi::ThrowException(vm_, error);
929     ASSERT_TRUE(vm_->GetJSThread()->HasPendingException());
930     TryCatch tryCatch(vm_);
931     tryCatch.GetAndClearException();
932     EXPECT_FALSE(vm_->GetJSThread()->HasPendingException());
933 }
934 /**
935  * @tc.number: ffi_interface_api_146
936  * @tc.name: Int32Array
937  * @tc.desc: trycatch class construction
938  * @tc.type: FUNC
939  * @tc.require:  parameter
940  */
HWTEST_F_L0(JSNApiTests,TryCatch)941 HWTEST_F_L0(JSNApiTests, TryCatch)
942 {
943     LocalScope scope(vm_);
944     TryCatch tryCatch(vm_);
945     EXPECT_EQ(tryCatch.getrethrow_(), false);
946     EXPECT_FALSE(tryCatch.HasCaught());
947     tryCatch.Rethrow();
948     EXPECT_EQ(tryCatch.getrethrow_(), true);
949 }
950 
HWTEST_F_L0(JSNApiTests,NewObjectWithProperties)951 HWTEST_F_L0(JSNApiTests, NewObjectWithProperties)
952 {
953     LocalScope scope(vm_);
954     Local<JSValueRef> keys[1100];
955     Local<JSValueRef> values[1100];
956     PropertyAttribute attributes[1100];
957     for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
958         for (int j = 0; j <= i; ++j) {
959             std::string strKey("TestKey" + std::to_string(i) + "_" + std::to_string(j));
960             std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
961             keys[j] = StringRef::NewFromUtf8(vm_, strKey.c_str());
962             values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
963             attributes[j] = PropertyAttribute(values[j], true, true, true);
964         }
965         Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, i + 1, keys, attributes);
966         for (int j = 0; j <= i; ++j) {
967             Local<JSValueRef> value1 = object->Get(vm_, keys[j]);
968             EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
969         }
970         JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
971         uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
972         if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
973             EXPECT_TRUE(propCount == 0);
974             EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
975             JSHandle<NameDictionary> dict(thread_, obj->GetProperties());
976             EXPECT_TRUE(dict->EntriesCount() == i + 1);
977         } else {
978             EXPECT_TRUE(propCount == i + 1);
979             int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
980             int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
981             if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
982                 EXPECT_TRUE(in_idx == i + 1);
983                 EXPECT_TRUE(nonin_idx == -1);
984             } else {
985                 EXPECT_TRUE(in_idx == -1);
986                 EXPECT_TRUE(nonin_idx == 0);
987             }
988         }
989     }
990 }
991 
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertieNonPureStringKey)992 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertieNonPureStringKey)
993 {
994     LocalScope scope(vm_);
995     Local<JSValueRef> keys[] = {
996         StringRef::NewFromUtf8(vm_, "1"),
997     };
998     Local<JSValueRef> values[] = {
999         StringRef::NewFromUtf8(vm_, "value1"),
1000     };
1001     PropertyAttribute attributes[] = {
1002         PropertyAttribute(values[0], true, true, true),
1003     };
1004     Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 1, keys, attributes);
1005     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1006     EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1007     thread_->ClearException();
1008 }
1009 
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicate)1010 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicate)
1011 {
1012     LocalScope scope(vm_);
1013     Local<JSValueRef> keys[] = {
1014         StringRef::NewFromUtf8(vm_, "duplicateKey"),
1015         StringRef::NewFromUtf8(vm_, "simpleKey"),
1016         StringRef::NewFromUtf8(vm_, "duplicateKey"),
1017     };
1018     Local<JSValueRef> values[] = {
1019         StringRef::NewFromUtf8(vm_, "value1"),
1020         StringRef::NewFromUtf8(vm_, "value2"),
1021         StringRef::NewFromUtf8(vm_, "value3"),
1022     };
1023     PropertyAttribute attributes[] = {
1024         PropertyAttribute(values[0], true, true, true),
1025         PropertyAttribute(values[1], true, true, true),
1026         PropertyAttribute(values[2], true, true, true),
1027     };
1028     Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1029     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1030     EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1031     thread_->ClearException();
1032 }
1033 
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedProperties)1034 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedProperties)
1035 {
1036     LocalScope scope(vm_);
1037     const char *keys[1100];
1038     std::string strKeys[1100];
1039     Local<JSValueRef> values[1100];
1040     for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
1041         for (int j = 0; j <= i; ++j) {
1042             strKeys[j] = "TestKey" + std::to_string(i) + "_" + std::to_string(j);
1043             std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
1044             keys[j] = const_cast<char *>(strKeys[j].c_str());
1045             values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
1046         }
1047         Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, i + 1, keys, values);
1048         for (int j = 0; j <= i; ++j) {
1049             Local<JSValueRef> value1 = object->Get(vm_, StringRef::NewFromUtf8(vm_, keys[j]));
1050             EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
1051         }
1052         JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
1053         uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
1054         if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
1055             EXPECT_TRUE(propCount == 0);
1056             EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
1057             JSHandle<NameDictionary> dict(thread_, obj->GetProperties());
1058             EXPECT_TRUE(dict->EntriesCount() == i + 1);
1059         } else {
1060             EXPECT_TRUE(propCount == i + 1);
1061             int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
1062             int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
1063             if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
1064                 EXPECT_TRUE(in_idx == i + 1);
1065                 EXPECT_TRUE(nonin_idx == -1);
1066             } else {
1067                 EXPECT_TRUE(in_idx == -1);
1068                 EXPECT_TRUE(nonin_idx == 0);
1069             }
1070         }
1071     }
1072 }
1073 
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertieNonPureStringKey)1074 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertieNonPureStringKey)
1075 {
1076     LocalScope scope(vm_);
1077     const char *keys[] = {
1078         "1",
1079     };
1080     Local<JSValueRef> values[] = {
1081         StringRef::NewFromUtf8(vm_, "value1"),
1082     };
1083     Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 2, keys, values);
1084     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1085     EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1086     thread_->ClearException();
1087 }
1088 
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertiesDuplicate)1089 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertiesDuplicate)
1090 {
1091     LocalScope scope(vm_);
1092     const char *keys[] = {
1093         "duplicateKey",
1094         "simpleKey",
1095         "duplicateKey",
1096     };
1097     Local<JSValueRef> values[] = {
1098         StringRef::NewFromUtf8(vm_, "value1"),
1099         StringRef::NewFromUtf8(vm_, "value2"),
1100         StringRef::NewFromUtf8(vm_, "value3"),
1101     };
1102     Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 3, keys, values);
1103     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1104     EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1105     thread_->ClearException();
1106 }
1107 
HWTEST_F_L0(JSNApiTests,GetNamedPropertyByPassingUtf8Key)1108 HWTEST_F_L0(JSNApiTests, GetNamedPropertyByPassingUtf8Key)
1109 {
1110     LocalScope scope(vm_);
1111     Local<ObjectRef> object = ObjectRef::New(vm_);
1112     const char* utf8Key = "TestKey";
1113     Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1114     Local<JSValueRef> value = ObjectRef::New(vm_);
1115     PropertyAttribute attribute(value, true, true, true);
1116 
1117     ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1118     Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1119     ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1120 }
1121 
HWTEST_F_L0(JSNApiTests,SetNamedPropertyByPassingUtf8Key)1122 HWTEST_F_L0(JSNApiTests, SetNamedPropertyByPassingUtf8Key)
1123 {
1124     LocalScope scope(vm_);
1125     Local<ObjectRef> object = ObjectRef::New(vm_);
1126     const char* utf8Key = "TestKey";
1127     Local<JSValueRef> value = ObjectRef::New(vm_);
1128 
1129     ASSERT_TRUE(object->Set(vm_, utf8Key, value));
1130     Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1131     ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1132 }
1133 
HWTEST_F_L0(JSNApiTests,NapiFastPathGetNamedProperty)1134 HWTEST_F_L0(JSNApiTests, NapiFastPathGetNamedProperty)
1135 {
1136     LocalScope scope(vm_);
1137     Local<ObjectRef> object = ObjectRef::New(vm_);
1138     const char* utf8Key = "TestKey";
1139     Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1140     Local<JSValueRef> value = ObjectRef::New(vm_);
1141     PropertyAttribute attribute(value, true, true, true);
1142 
1143     ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1144     Local<JSValueRef> value1 = JSNApi::NapiGetNamedProperty(vm_, reinterpret_cast<uintptr_t>(*object), utf8Key);
1145     ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1146 }
1147 
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)1148 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)
1149 {
1150     LocalScope scope(vm_);
1151     Local<JSValueRef> keys[] = {
1152         StringRef::NewFromUtf8WithoutStringTable(vm_, "duplicateKey"),
1153         StringRef::NewFromUtf8WithoutStringTable(vm_, "simpleKey"),
1154         StringRef::NewFromUtf8WithoutStringTable(vm_, "duplicateKey"),
1155     };
1156     Local<JSValueRef> values[] = {
1157         StringRef::NewFromUtf8WithoutStringTable(vm_, "value1"),
1158         StringRef::NewFromUtf8WithoutStringTable(vm_, "value2"),
1159         StringRef::NewFromUtf8WithoutStringTable(vm_, "value3"),
1160     };
1161     PropertyAttribute attributes[] = {
1162         PropertyAttribute(values[0], true, true, true),
1163         PropertyAttribute(values[1], true, true, true),
1164         PropertyAttribute(values[2], true, true, true),
1165     };
1166     Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1167     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1168     EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1169     thread_->ClearException();
1170 }
1171 
HWTEST_F_L0(JSNApiTests,EcmaObjectToInt)1172 HWTEST_F_L0(JSNApiTests, EcmaObjectToInt)
1173 {
1174     LocalScope scope(vm_);
1175     Local<FunctionRef> toPrimitiveFunc = FunctionRef::New(vm_,
1176         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1177             EcmaVM *vm = runtimeInfo->GetVM();
1178             return JSValueRef::True(vm);
1179         });
1180     Local<ObjectRef> obj = ObjectRef::New(vm_);
1181     PropertyAttribute attribute(toPrimitiveFunc, true, true, true);
1182     Local<JSValueRef> toPrimitiveKey = JSNApiHelper::ToLocal<JSValueRef>(vm_->GetGlobalEnv()->GetToPrimitiveSymbol());
1183     obj->DefineProperty(vm_, toPrimitiveKey, attribute);
1184     {
1185         // Test that Uint32Value and Int32Value should transition to Running if needed.
1186         ThreadNativeScope nativeScope(thread_);
1187         uint32_t res = obj->Uint32Value(vm_);
1188         EXPECT_TRUE(res == 1);
1189         res = obj->Int32Value(vm_);
1190         EXPECT_TRUE(res == 1);
1191     }
1192 }
1193 
HWTEST_F_L0(JSNApiTests,NapiTryFastTest)1194 HWTEST_F_L0(JSNApiTests, NapiTryFastTest)
1195 {
1196     Local<ObjectRef> object = ObjectRef::New(vm_);
1197     JSTaggedValue a(0);
1198     JSHandle<JSTaggedValue> handle(thread_, a);
1199     Local<JSValueRef> key = JSNApiHelper::ToLocal<JSValueRef>(handle);
1200     const char* utf8Key = "TestKey";
1201     Local<JSValueRef> key2 = StringRef::NewFromUtf8(vm_, utf8Key);
1202     Local<JSValueRef> value = ObjectRef::New(vm_);
1203     object->Set(vm_, key, value);
1204     object->Set(vm_, key2, value);
1205     Local<JSValueRef> res1 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1206                                                        reinterpret_cast<uintptr_t>(*key));
1207     ASSERT_TRUE(value->IsStrictEquals(vm_, res1));
1208     Local<JSValueRef> res2 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1209                                                        reinterpret_cast<uintptr_t>(*key2));
1210     ASSERT_TRUE(value->IsStrictEquals(vm_, res2));
1211 
1212     Local<JSValueRef> flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1213                                                      reinterpret_cast<uintptr_t>(*key));
1214     ASSERT_TRUE(flag->BooleaValue(vm_));
1215     flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1216     ASSERT_TRUE(flag->BooleaValue(vm_));
1217 
1218     flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1219     ASSERT_TRUE(flag->BooleaValue(vm_));
1220     flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1221     ASSERT_TRUE(flag->BooleaValue(vm_));
1222 
1223     flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1224     ASSERT_FALSE(flag->BooleaValue(vm_));
1225     flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1226     ASSERT_FALSE(flag->BooleaValue(vm_));
1227 }
1228 
HWTEST_F_L0(JSNApiTests,NapiTryFastHasMethodTest)1229 HWTEST_F_L0(JSNApiTests, NapiTryFastHasMethodTest)
1230 {
1231     LocalScope scope(vm_);
1232     auto array = JSArray::ArrayCreate(thread_, JSTaggedNumber(0));
1233     auto arr = JSNApiHelper::ToLocal<ObjectRef>(array);
1234     const char* utf8Key = "concat";
1235     Local<JSValueRef> key3 = StringRef::NewFromUtf8(vm_, utf8Key);
1236     auto flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*arr), reinterpret_cast<uintptr_t>(*key3));
1237     ASSERT_TRUE(flag->BooleaValue(vm_));
1238 }
1239 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest001)1240 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest001)
1241 {
1242     isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, 0);
1243     ASSERT_FALSE(isStringCacheTableCreated_);
1244 }
1245 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest002)1246 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest002)
1247 {
1248     constexpr uint32_t STRING_CACHE_TABLE_SIZE = 300;
1249     isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1250     ASSERT_FALSE(isStringCacheTableCreated_);
1251 }
1252 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest003)1253 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest003)
1254 {
1255     constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
1256     isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1257     ASSERT_TRUE(isStringCacheTableCreated_);
1258 }
1259 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest004)1260 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest004)
1261 {
1262     RegisterStringCacheTable();
1263     constexpr uint32_t PROPERTY_INDEX = 101;
1264     constexpr char property[] = "hello";
1265     auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1266     ASSERT_FALSE(res);
1267 }
1268 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest005)1269 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest005)
1270 {
1271     RegisterStringCacheTable();
1272     constexpr uint32_t PROPERTY_INDEX = 0;
1273     constexpr char property[] = "hello";
1274     auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1275     ASSERT_TRUE(res);
1276 }
1277 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest006)1278 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest006)
1279 {
1280     RegisterStringCacheTable();
1281     constexpr uint32_t PROPERTY_INDEX = 1;
1282     constexpr char property[] = "hello";
1283     auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1284     ASSERT_TRUE(res);
1285 
1286     constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1287     res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1288     ASSERT_FALSE(res);
1289 }
1290 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest007)1291 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest007)
1292 {
1293     RegisterStringCacheTable();
1294     constexpr uint32_t PROPERTY_INDEX = 2;
1295     constexpr char property[] = "hello";
1296     auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1297     ASSERT_TRUE(res);
1298 
1299     constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1300     res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1301     ASSERT_TRUE(res);
1302 }
1303 
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest008)1304 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest008)
1305 {
1306     RegisterStringCacheTable();
1307     constexpr uint32_t PROPERTY_INDEX = 3;
1308     constexpr char property[] = "hello world";
1309     auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1310     ASSERT_TRUE(res);
1311     Local<StringRef> value = ExternalStringCache::GetCachedString(vm_, PROPERTY_INDEX);
1312     ASSERT_FALSE(value->IsUndefined());
1313     EXPECT_EQ(value->ToString(vm_), property);
1314 }
1315 
HWTEST_F_L0(JSNApiTests,SetExecuteMode)1316 HWTEST_F_L0(JSNApiTests, SetExecuteMode)
1317 {
1318     ecmascript::ModuleManager *moduleManager = thread_->GetCurrentEcmaContext()->GetModuleManager();
1319     ecmascript::ModuleExecuteMode res1 = moduleManager->GetExecuteMode();
1320     EXPECT_EQ(res1, ecmascript::ModuleExecuteMode::ExecuteZipMode);
1321 
1322     JSNApi::SetExecuteBufferMode(vm_);
1323     ecmascript::ModuleExecuteMode res2 = moduleManager->GetExecuteMode();
1324     EXPECT_EQ(res2, ecmascript::ModuleExecuteMode::ExecuteBufferMode);
1325 }
1326 } // namespace panda::test
1327