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