1 /*
2 * Copyright (c) 2021 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 "ecmascript/tests/test_helper.h"
17
18 #include <cstddef>
19 #include "ecmascript/builtins/builtins_function.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_thread.h"
23 #include "ecmascript/napi/include/jsnapi.h"
24 #include "ecmascript/napi/jsnapi_helper-inl.h"
25 #include "ecmascript/object_factory.h"
26
27 using namespace panda;
28 using namespace panda::ecmascript;
29
30 namespace panda::test {
31 using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction;
32 class JSNApiTests : public testing::Test {
33 public:
SetUpTestCase()34 static void SetUpTestCase()
35 {
36 GTEST_LOG_(INFO) << "SetUpTestCase";
37 }
38
TearDownTestCase()39 static void TearDownTestCase()
40 {
41 GTEST_LOG_(INFO) << "TearDownCase";
42 }
43
SetUp()44 void SetUp() override
45 {
46 RuntimeOption option;
47 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
48 vm_ = JSNApi::CreateJSVM(option);
49 ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
50 thread_ = vm_->GetJSThread();
51 vm_->SetEnableForceGC(true);
52 }
53
TearDown()54 void TearDown() override
55 {
56 vm_->SetEnableForceGC(false);
57 JSNApi::DestroyJSVM(vm_);
58 }
59
60 protected:
61 JSThread *thread_ = nullptr;
62 EcmaVM *vm_ = nullptr;
63 };
64
FunctionCallback(EcmaVM * vm,Local<JSValueRef>,const Local<JSValueRef> *,int32_t length,void *)65 Local<JSValueRef> FunctionCallback(EcmaVM *vm, Local<JSValueRef>, const Local<JSValueRef> *, int32_t length, void *)
66 {
67 EscapeLocalScope scope(vm);
68 return scope.Escape(ArrayRef::New(vm, length));
69 }
70
ThreadCheck(const EcmaVM * vm)71 void ThreadCheck(const EcmaVM *vm)
72 {
73 EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId());
74 }
75
HWTEST_F_L0(JSNApiTests,GetGlobalObject)76 HWTEST_F_L0(JSNApiTests, GetGlobalObject)
77 {
78 LocalScope scope(vm_);
79 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
80 ASSERT_FALSE(globalObject.IsEmpty());
81 ASSERT_TRUE(globalObject->IsObject());
82 }
83
HWTEST_F_L0(JSNApiTests,ThreadIdCheck)84 HWTEST_F_L0(JSNApiTests, ThreadIdCheck)
85 {
86 EXPECT_TRUE(vm_->GetJSThread()->GetThreadId() == JSThread::GetCurrentThreadId());
87 #if defined(ECMASCRIPT_ENABLE_THREAD_CHECK) && !ECMASCRIPT_ENABLE_THREAD_CHECK
88 std::thread testThread(ThreadCheck, vm_);
89 testThread.join();
90 #endif
91 }
92
HWTEST_F_L0(JSNApiTests,RegisterFunction)93 HWTEST_F_L0(JSNApiTests, RegisterFunction)
94 {
95 LocalScope scope(vm_);
96 Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback, nullptr);
97 ASSERT_TRUE(!callback.IsEmpty());
98 std::vector<Local<JSValueRef>> arguments;
99 arguments.emplace_back(JSValueRef::Undefined(vm_));
100 Local<JSValueRef> result =
101 callback->Call(vm_, JSValueRef::Undefined(vm_), arguments.data(), arguments.size());
102 ASSERT_TRUE(result->IsArray(vm_));
103 Local<ArrayRef> array(result);
104 ASSERT_EQ(array->Length(vm_), arguments.size());
105 }
106
HWTEST_F_L0(JSNApiTests,GetProperty)107 HWTEST_F_L0(JSNApiTests, GetProperty)
108 {
109 LocalScope scope(vm_);
110 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
111 ASSERT_FALSE(globalObject.IsEmpty());
112 ASSERT_TRUE(globalObject->IsObject());
113
114 Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Number");
115 Local<ObjectRef> property = globalObject->Get(vm_, key);
116 ASSERT_TRUE(property->IsFunction());
117 }
118
HWTEST_F_L0(JSNApiTests,SetProperty)119 HWTEST_F_L0(JSNApiTests, SetProperty)
120 {
121 LocalScope scope(vm_);
122 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
123 ASSERT_FALSE(globalObject.IsEmpty());
124 ASSERT_TRUE(globalObject->IsObject());
125
126 Local<ArrayRef> property = ArrayRef::New(vm_, 3); // 3 : length
127 ASSERT_TRUE(property->IsArray(vm_));
128 ASSERT_EQ(property->Length(vm_), 3); // 3 : test case of input
129
130 Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Test");
131 bool result = globalObject->Set(vm_, key, property);
132 ASSERT_TRUE(result);
133
134 Local<ObjectRef> propertyGet = globalObject->Get(vm_, key);
135 ASSERT_TRUE(propertyGet->IsArray(vm_));
136 ASSERT_EQ(Local<ArrayRef>(propertyGet)->Length(vm_), 3); // 3 : test case of input
137 }
138
HWTEST_F_L0(JSNApiTests,JsonParser)139 HWTEST_F_L0(JSNApiTests, JsonParser)
140 {
141 LocalScope scope(vm_);
142 Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
143 ASSERT_FALSE(globalObject.IsEmpty());
144 ASSERT_TRUE(globalObject->IsObject());
145
146 const char *const test{R"({"orientation": "portrait"})"};
147 Local<ObjectRef> jsonString = StringRef::NewFromUtf8(vm_, test);
148
149 Local<JSValueRef> result = JSON::Parse(vm_, jsonString);
150 ASSERT_TRUE(result->IsObject());
151
152 Local<ObjectRef> keyString = StringRef::NewFromUtf8(vm_, "orientation");
153 Local<JSValueRef> property = Local<ObjectRef>(result)->Get(vm_, keyString);
154 ASSERT_TRUE(property->IsString());
155 }
156
HWTEST_F_L0(JSNApiTests,StrictEqual)157 HWTEST_F_L0(JSNApiTests, StrictEqual)
158 {
159 LocalScope scope(vm_);
160 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1");
161 Local<StringRef> target1 = StringRef::NewFromUtf8(vm_, "1");
162 Local<NumberRef> target = NumberRef::New(vm_, 1);
163
164 ASSERT_FALSE(origin->IsStrictEquals(vm_, target));
165 ASSERT_TRUE(origin->IsStrictEquals(vm_, target1));
166 }
167
HWTEST_F_L0(JSNApiTests,InstanceOf)168 HWTEST_F_L0(JSNApiTests, InstanceOf)
169 {
170 LocalScope scope(vm_);
171 Local<FunctionRef> target = FunctionRef::New(vm_, nullptr, nullptr);
172 Local<ArrayRef> origin = ArrayRef::New(vm_, 1);
173
174 ASSERT_FALSE(origin->InstanceOf(vm_, target));
175 }
176
HWTEST_F_L0(JSNApiTests,TypeOf)177 HWTEST_F_L0(JSNApiTests, TypeOf)
178 {
179 LocalScope scope(vm_);
180 Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1");
181 Local<StringRef> typeString = origin->Typeof(vm_);
182 ASSERT_EQ(typeString->ToString(), "string");
183
184 Local<NumberRef> target = NumberRef::New(vm_, 1);
185 typeString = target->Typeof(vm_);
186 ASSERT_EQ(typeString->ToString(), "number");
187 }
188
HWTEST_F_L0(JSNApiTests,Symbol)189 HWTEST_F_L0(JSNApiTests, Symbol)
190 {
191 LocalScope scope(vm_);
192 Local<StringRef> description = StringRef::NewFromUtf8(vm_, "test");
193 Local<SymbolRef> symbol = SymbolRef::New(vm_, description);
194
195 ASSERT_FALSE(description->IsSymbol());
196 ASSERT_TRUE(symbol->IsSymbol());
197 }
198
HWTEST_F_L0(JSNApiTests,StringUtf8_001)199 HWTEST_F_L0(JSNApiTests, StringUtf8_001)
200 {
201 LocalScope scope(vm_);
202 std::string test = "Hello world";
203 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str());
204
205 EXPECT_TRUE(testString->Utf8Length() == 12); // 12 : length of testString("Hello World")
206 char buffer[12]; // 12 : length of testString
207 EXPECT_TRUE(testString->WriteUtf8(buffer, 12) == 12); // 12 : length of testString("Hello World")
208 std::string res(buffer);
209 ASSERT_EQ(res, test);
210 }
211
HWTEST_F_L0(JSNApiTests,StringUtf8_002)212 HWTEST_F_L0(JSNApiTests, StringUtf8_002)
213 {
214 LocalScope scope(vm_);
215 std::string test = "年";
216 Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str());
217
218 EXPECT_TRUE(testString->Utf8Length() == 4); // 4 : length of testString("年")
219 char buffer[4]; // 4 : length of testString
220 EXPECT_TRUE(testString->WriteUtf8(buffer, 4) == 4); // 4 : length of testString("年")
221 std::string res(buffer);
222 ASSERT_EQ(res, test);
223 }
224
HWTEST_F_L0(JSNApiTests,ToType)225 HWTEST_F_L0(JSNApiTests, ToType)
226 {
227 LocalScope scope(vm_);
228 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3");
229 Local<JSValueRef> toValue(toString);
230
231 ASSERT_EQ(toString->ToNumber(vm_)->Value(), -123.3); // -123 : test case of input
232 ASSERT_EQ(toString->ToBoolean(vm_)->Value(), true);
233 ASSERT_EQ(toValue->ToString(vm_)->ToString(), "-123.3");
234 ASSERT_TRUE(toValue->ToObject(vm_)->IsObject());
235 }
236
HWTEST_F_L0(JSNApiTests,TypeValue)237 HWTEST_F_L0(JSNApiTests, TypeValue)
238 {
239 LocalScope scope(vm_);
240 Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123");
241 Local<JSValueRef> toValue(toString);
242
243 ASSERT_EQ(toString->Int32Value(vm_), -123); // -123 : test case of input
244 ASSERT_EQ(toString->BooleaValue(), true);
245 ASSERT_EQ(toString->Uint32Value(vm_), 4294967173); // 4294967173 : test case of input
246 ASSERT_EQ(toString->IntegerValue(vm_), -123); // -123 : test case of input
247 }
248
HWTEST_F_L0(JSNApiTests,DefineProperty)249 HWTEST_F_L0(JSNApiTests, DefineProperty)
250 {
251 LocalScope scope(vm_);
252 Local<ObjectRef> object = ObjectRef::New(vm_);
253 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
254 Local<JSValueRef> value = ObjectRef::New(vm_);
255 PropertyAttribute attribute(value, true, true, true);
256
257 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
258 Local<JSValueRef> value1 = object->Get(vm_, key);
259 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
260 }
261
HWTEST_F_L0(JSNApiTests,HasProperty)262 HWTEST_F_L0(JSNApiTests, HasProperty)
263 {
264 LocalScope scope(vm_);
265 Local<ObjectRef> object = ObjectRef::New(vm_);
266 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
267 Local<JSValueRef> value = ObjectRef::New(vm_);
268 PropertyAttribute attribute(value, true, true, true);
269
270 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
271 ASSERT_TRUE(object->Has(vm_, key));
272 }
273
HWTEST_F_L0(JSNApiTests,DeleteProperty)274 HWTEST_F_L0(JSNApiTests, DeleteProperty)
275 {
276 LocalScope scope(vm_);
277 Local<ObjectRef> object = ObjectRef::New(vm_);
278 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
279 Local<JSValueRef> value = ObjectRef::New(vm_);
280 PropertyAttribute attribute(value, true, true, true);
281
282 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
283 ASSERT_TRUE(object->Delete(vm_, key));
284 ASSERT_FALSE(object->Has(vm_, key));
285 }
286
HWTEST_F_L0(JSNApiTests,GetProtoType)287 HWTEST_F_L0(JSNApiTests, GetProtoType)
288 {
289 LocalScope scope(vm_);
290 Local<FunctionRef> function = FunctionRef::New(vm_, nullptr, nullptr);
291 Local<JSValueRef> protoType = function->GetPrototype(vm_);
292 ASSERT_TRUE(protoType->IsObject());
293
294 Local<FunctionRef> object = ObjectRef::New(vm_);
295 protoType = object->GetPrototype(vm_);
296 ASSERT_TRUE(protoType->IsObject());
297 }
298
CheckReject(EcmaVM *,Local<JSValueRef>,const Local<JSValueRef> argv[],int32_t length,void *)299 void CheckReject(EcmaVM *, Local<JSValueRef>, const Local<JSValueRef> argv[], int32_t length, void *)
300 {
301 ASSERT_EQ(length, 1);
302 Local<JSValueRef> reason = argv[0];
303 ASSERT_TRUE(reason->IsString());
304 ASSERT_EQ(Local<StringRef>(reason)->ToString(), "Reject");
305 }
306
RejectCallback(EcmaVM * vm,Local<JSValueRef> thisArg,const Local<JSValueRef> argv[],int32_t length,void * data)307 Local<JSValueRef> RejectCallback(EcmaVM *vm, Local<JSValueRef> thisArg, const Local<JSValueRef> argv[], int32_t length,
308 void *data)
309 {
310 LocalScope scope(vm);
311 CheckReject(vm, thisArg, argv, length, data);
312 return JSValueRef::Undefined(vm);
313 }
314
HWTEST_F_L0(JSNApiTests,PromiseCatch)315 HWTEST_F_L0(JSNApiTests, PromiseCatch)
316 {
317 LocalScope scope(vm_);
318 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
319
320 Local<PromiseRef> promise = capability->GetPromise(vm_);
321 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback, nullptr);
322 Local<PromiseRef> catchPromise = promise->Catch(vm_, reject);
323 ASSERT_TRUE(promise->IsPromise());
324 ASSERT_TRUE(catchPromise->IsPromise());
325
326 Local<StringRef> reason = StringRef::NewFromUtf8(vm_, "Reject");
327 ASSERT_TRUE(capability->Reject(vm_, reason));
328
329 vm_->ExecutePromisePendingJob();
330 }
331
CheckResolve(EcmaVM *,Local<JSValueRef>,const Local<JSValueRef> argv[],int32_t length,void *)332 void CheckResolve(EcmaVM *, Local<JSValueRef>, const Local<JSValueRef> argv[], int32_t length, void *)
333 {
334 ASSERT_EQ(length, 1);
335 Local<JSValueRef> value = argv[0];
336 ASSERT_TRUE(value->IsNumber());
337 ASSERT_EQ(Local<NumberRef>(value)->Value(), 300.3); // 300.3 : test case of input
338 }
339
ResolvedCallback(EcmaVM * vm,Local<JSValueRef> thisArg,const Local<JSValueRef> argv[],int32_t length,void * data)340 Local<JSValueRef> ResolvedCallback(EcmaVM *vm, Local<JSValueRef> thisArg, const Local<JSValueRef> argv[],
341 int32_t length, void *data)
342 {
343 LocalScope scope(vm);
344 CheckResolve(vm, thisArg, argv, length, data);
345 return JSValueRef::Undefined(vm);
346 }
347
HWTEST_F_L0(JSNApiTests,PromiseThen)348 HWTEST_F_L0(JSNApiTests, PromiseThen)
349 {
350 LocalScope scope(vm_);
351 Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
352
353 Local<PromiseRef> promise = capability->GetPromise(vm_);
354 Local<FunctionRef> resolve = FunctionRef::New(vm_, ResolvedCallback, nullptr);
355 Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback, nullptr);
356 Local<PromiseRef> thenPromise = promise->Then(vm_, resolve, reject);
357 ASSERT_TRUE(promise->IsPromise());
358 ASSERT_TRUE(thenPromise->IsPromise());
359
360 Local<StringRef> value = NumberRef::New(vm_, 300.3); // 300.3 : test case of input
361 ASSERT_TRUE(capability->Resolve(vm_, value));
362 vm_->ExecutePromisePendingJob();
363 }
364
HWTEST_F_L0(JSNApiTests,Constructor)365 HWTEST_F_L0(JSNApiTests, Constructor)
366 {
367 LocalScope scope(vm_);
368 Local<ObjectRef> object = JSNApi::GetGlobalObject(vm_);
369 Local<StringRef> key = StringRef::NewFromUtf8(vm_, "Number");
370 Local<FunctionRef> numberConstructor = object->Get(vm_, key);
371 Local<JSValueRef> argv[1];
372 argv[0] = NumberRef::New(vm_, 1.3); // 1.3 : test case of input
373 Local<JSValueRef> result = numberConstructor->Constructor(vm_, argv, 1);
374 ASSERT_TRUE(result->IsObject());
375 ASSERT_EQ(result->ToNumber(vm_)->Value(), 1.3); // 1.3 : size of arguments
376 }
377
HWTEST_F_L0(JSNApiTests,ArrayBuffer)378 HWTEST_F_L0(JSNApiTests, ArrayBuffer)
379 {
380 LocalScope scope(vm_);
381 const int32_t length = 15;
382 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
383 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
384 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
385 ASSERT_NE(arrayBuffer->GetBuffer(), nullptr);
386 JSNApi::TriggerGC(vm_);
387 }
388
HWTEST_F_L0(JSNApiTests,ArrayBufferWithBuffer)389 HWTEST_F_L0(JSNApiTests, ArrayBufferWithBuffer)
390 {
391 static bool isFree = false;
392 struct Data {
393 int32_t length;
394 };
395 const int32_t length = 15;
396 Data *data = new Data();
397 data->length = length;
398 Deleter deleter = [](void *buffer, void *data) -> void {
399 delete[] reinterpret_cast<uint8_t *>(buffer);
400 Data *currentData = reinterpret_cast<Data *>(data);
401 ASSERT_EQ(currentData->length, 15); // 5 : size of arguments
402 delete currentData;
403 isFree = true;
404 };
405 {
406 LocalScope scope(vm_);
407 uint8_t *buffer = new uint8_t[length]();
408 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
409 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
410 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
411 ASSERT_EQ(arrayBuffer->GetBuffer(), buffer);
412 }
413 JSNApi::TriggerGC(vm_, JSNApi::TRIGGER_GC_TYPE::FULL_GC);
414 ASSERT_TRUE(isFree);
415 }
416
HWTEST_F_L0(JSNApiTests,DataView)417 HWTEST_F_L0(JSNApiTests, DataView)
418 {
419 LocalScope scope(vm_);
420 const int32_t length = 15;
421 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
422 JSNApi::TriggerGC(vm_);
423 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
424
425 // 5 : offset of byte, 7 : length
426 Local<DataViewRef> dataView = DataViewRef::New(vm_, arrayBuffer, 5, 7);
427 ASSERT_TRUE(dataView->IsDataView());
428 ASSERT_EQ(dataView->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
429 ASSERT_EQ(dataView->ByteLength(), 7); // 7 : size of arguments
430 ASSERT_EQ(dataView->ByteOffset(), 5); // 5 : size of arguments
431
432 // 5 : offset of byte, 11 : length
433 dataView = DataViewRef::New(vm_, arrayBuffer, 5, 11);
434 ASSERT_TRUE(dataView->IsException());
435 }
436
HWTEST_F_L0(JSNApiTests,Int8Array)437 HWTEST_F_L0(JSNApiTests, Int8Array)
438 {
439 LocalScope scope(vm_);
440 const int32_t length = 15;
441 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
442 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
443
444 // 5 : offset of byte, 6 : length
445 Local<Int8ArrayRef> typedArray = Int8ArrayRef::New(vm_, arrayBuffer, 5, 6);
446 ASSERT_TRUE(typedArray->IsInt8Array());
447 ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
448 ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
449 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
450 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
451 }
452
HWTEST_F_L0(JSNApiTests,Uint8Array)453 HWTEST_F_L0(JSNApiTests, Uint8Array)
454 {
455 LocalScope scope(vm_);
456 const int32_t length = 15;
457 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
458 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
459
460 // 5 : offset of byte, 6 : length
461 Local<Uint8ArrayRef> typedArray = Uint8ArrayRef::New(vm_, arrayBuffer, 5, 6);
462 ASSERT_TRUE(typedArray->IsUint8Array());
463 ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
464 ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
465 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
466 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
467 }
468
HWTEST_F_L0(JSNApiTests,Uint8ClampedArray)469 HWTEST_F_L0(JSNApiTests, Uint8ClampedArray)
470 {
471 LocalScope scope(vm_);
472 const int32_t length = 15;
473 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
474 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
475
476 // 5 : offset of byte, 6 : length
477 Local<Uint8ClampedArrayRef> typedArray = Uint8ClampedArrayRef::New(vm_, arrayBuffer, 5, 6);
478 ASSERT_TRUE(typedArray->IsUint8ClampedArray());
479 ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
480 ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
481 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
482 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
483 }
484
HWTEST_F_L0(JSNApiTests,Int16Array)485 HWTEST_F_L0(JSNApiTests, Int16Array)
486 {
487 LocalScope scope(vm_);
488 const int32_t length = 30;
489 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
490 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
491
492 // 4 : offset of byte, 6 : length
493 Local<Int16ArrayRef> typedArray = Int16ArrayRef::New(vm_, arrayBuffer, 4, 6);
494 ASSERT_TRUE(typedArray->IsInt16Array());
495 ASSERT_EQ(typedArray->ByteLength(vm_), 12); // 12 : length of bytes
496 ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
497 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
498 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
499 }
500
HWTEST_F_L0(JSNApiTests,Uint16Array)501 HWTEST_F_L0(JSNApiTests, Uint16Array)
502 {
503 LocalScope scope(vm_);
504 const int32_t length = 30;
505 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
506 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
507
508 // 4 : offset of byte, 6 : length
509 Local<Uint16ArrayRef> typedArray = Uint16ArrayRef::New(vm_, arrayBuffer, 4, 6);
510 ASSERT_TRUE(typedArray->IsUint16Array());
511 ASSERT_EQ(typedArray->ByteLength(vm_), 12); // 12 : length of bytes
512 ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
513 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
514 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
515 }
516
HWTEST_F_L0(JSNApiTests,Uint32Array)517 HWTEST_F_L0(JSNApiTests, Uint32Array)
518 {
519 LocalScope scope(vm_);
520 const int32_t length = 30;
521 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
522 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
523
524 // 4 : offset of byte, 6 : length
525 Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, 4, 6);
526 ASSERT_TRUE(typedArray->IsUint32Array());
527 ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
528 ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
529 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
530 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
531 }
532
HWTEST_F_L0(JSNApiTests,Int32Array)533 HWTEST_F_L0(JSNApiTests, Int32Array)
534 {
535 LocalScope scope(vm_);
536 const int32_t length = 30;
537 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
538 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
539
540 // 4 : offset of byte, 6 : length
541 Local<Int32ArrayRef> typedArray = Int32ArrayRef::New(vm_, arrayBuffer, 4, 6);
542 ASSERT_TRUE(typedArray->IsInt32Array());
543 ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
544 ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
545 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
546 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
547 }
548
HWTEST_F_L0(JSNApiTests,Float32Array)549 HWTEST_F_L0(JSNApiTests, Float32Array)
550 {
551 LocalScope scope(vm_);
552 const int32_t length = 30;
553 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
554 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
555
556 // 4 : offset of byte, 6 : length
557 Local<Float32ArrayRef> typedArray = Float32ArrayRef::New(vm_, arrayBuffer, 4, 6);
558 ASSERT_TRUE(typedArray->IsFloat32Array());
559 ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
560 ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
561 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
562 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
563 }
564
HWTEST_F_L0(JSNApiTests,Float64Array)565 HWTEST_F_L0(JSNApiTests, Float64Array)
566 {
567 LocalScope scope(vm_);
568 const int32_t length = 57;
569 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
570 ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
571
572 // 8 : offset of byte, 6 : length
573 Local<Float64ArrayRef> typedArray = Float64ArrayRef::New(vm_, arrayBuffer, 8, 6);
574 ASSERT_TRUE(typedArray->IsFloat64Array());
575 ASSERT_EQ(typedArray->ByteLength(vm_), 48); // 48 : length of bytes
576 ASSERT_EQ(typedArray->ByteOffset(vm_), 8); // 8 : offset of byte
577 ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
578 ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
579 }
580
HWTEST_F_L0(JSNApiTests,Error)581 HWTEST_F_L0(JSNApiTests, Error)
582 {
583 LocalScope scope(vm_);
584 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
585 Local<JSValueRef> error = Exception::Error(vm_, message);
586 ASSERT_TRUE(error->IsError());
587
588 JSNApi::ThrowException(vm_, error);
589 ASSERT_TRUE(thread_->HasPendingException());
590 }
591
HWTEST_F_L0(JSNApiTests,RangeError)592 HWTEST_F_L0(JSNApiTests, RangeError)
593 {
594 LocalScope scope(vm_);
595 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
596 Local<JSValueRef> error = Exception::RangeError(vm_, message);
597 ASSERT_TRUE(error->IsError());
598
599 JSNApi::ThrowException(vm_, error);
600 ASSERT_TRUE(thread_->HasPendingException());
601 }
602
HWTEST_F_L0(JSNApiTests,TypeError)603 HWTEST_F_L0(JSNApiTests, TypeError)
604 {
605 LocalScope scope(vm_);
606 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
607 Local<JSValueRef> error = Exception::TypeError(vm_, message);
608 ASSERT_TRUE(error->IsError());
609
610 JSNApi::ThrowException(vm_, error);
611 ASSERT_TRUE(thread_->HasPendingException());
612 }
613
HWTEST_F_L0(JSNApiTests,ReferenceError)614 HWTEST_F_L0(JSNApiTests, ReferenceError)
615 {
616 LocalScope scope(vm_);
617 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
618 Local<JSValueRef> error = Exception::ReferenceError(vm_, message);
619 ASSERT_TRUE(error->IsError());
620
621 JSNApi::ThrowException(vm_, error);
622 ASSERT_TRUE(thread_->HasPendingException());
623 }
624
HWTEST_F_L0(JSNApiTests,SyntaxError)625 HWTEST_F_L0(JSNApiTests, SyntaxError)
626 {
627 LocalScope scope(vm_);
628 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
629 Local<JSValueRef> error = Exception::SyntaxError(vm_, message);
630 ASSERT_TRUE(error->IsError());
631
632 JSNApi::ThrowException(vm_, error);
633 ASSERT_TRUE(thread_->HasPendingException());
634 }
635
HWTEST_F_L0(JSNApiTests,InheritPrototype_001)636 HWTEST_F_L0(JSNApiTests, InheritPrototype_001)
637 {
638 LocalScope scope(vm_);
639 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
640 // new with Builtins::Set Prototype
641 JSHandle<JSTaggedValue> set = env->GetBuiltinsSetFunction();
642 Local<FunctionRef> setLocal = JSNApiHelper::ToLocal<FunctionRef>(set);
643 // new with Builtins::Map Prototype
644 JSHandle<JSTaggedValue> map = env->GetBuiltinsMapFunction();
645 Local<FunctionRef> mapLocal = JSNApiHelper::ToLocal<FunctionRef>(map);
646 JSHandle<JSTaggedValue> setPrototype(thread_, JSHandle<JSFunction>::Cast(set)->GetFunctionPrototype());
647 JSHandle<JSTaggedValue> mapPrototype(thread_, JSHandle<JSFunction>::Cast(map)->GetFunctionPrototype());
648 JSHandle<JSTaggedValue> mapPrototypeProto(thread_, JSHandle<JSObject>::Cast(mapPrototype)->GetPrototype(thread_));
649 bool same = JSTaggedValue::SameValue(setPrototype, mapPrototypeProto);
650 // before inherit, map.Prototype.__proto__ should be different from set.Prototype
651 ASSERT_FALSE(same);
652 // before inherit, map.__proto__ should be different from set
653 JSHandle<JSTaggedValue> mapProto(thread_, JSHandle<JSObject>::Cast(map)->GetPrototype(thread_));
654 bool same1 = JSTaggedValue::SameValue(set, mapProto);
655 ASSERT_FALSE(same1);
656
657 // Set property to Set Function
658 auto factory = vm_->GetFactory();
659 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
660 PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString);
661 bool success = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), defaultString, desc);
662 ASSERT_TRUE(success);
663 JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromCanBeCompressString("property1").GetTaggedValue());
664 JSHandle<JSTaggedValue> func = env->GetTypedArrayFunction();
665 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
666 bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), property1String, desc1);
667 ASSERT_TRUE(success1);
668
669 mapLocal->Inherit(vm_, setLocal);
670 JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(mapLocal);
671 JSHandle<JSTaggedValue> sonPrototype(thread_, JSHandle<JSFunction>::Cast(sonHandle)->GetFunctionPrototype());
672 JSHandle<JSTaggedValue> sonPrototypeProto(thread_, JSHandle<JSObject>::Cast(sonPrototype)->GetPrototype(thread_));
673 bool same2 = JSTaggedValue::SameValue(setPrototype, sonPrototypeProto);
674 ASSERT_TRUE(same2);
675 JSHandle<JSTaggedValue> sonProto(thread_, JSHandle<JSObject>::Cast(map)->GetPrototype(thread_));
676 bool same3 = JSTaggedValue::SameValue(set, sonProto);
677 ASSERT_TRUE(same3);
678
679 // son = new Son(), Son() inherit from Parent(), Test whether son.InstanceOf(Parent) is true
680 JSHandle<JSObject> sonObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle);
681 bool isInstance = JSObject::InstanceOf(thread_, JSHandle<JSTaggedValue>::Cast(sonObj), set);
682 ASSERT_TRUE(isInstance);
683
684 // Test whether son Function can access to property of parent Function
685 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), defaultString);
686 bool same4 = JSTaggedValue::SameValue(defaultString, res.GetValue());
687 ASSERT_TRUE(same4);
688 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), property1String);
689 bool same5 = JSTaggedValue::SameValue(func, res1.GetValue());
690 ASSERT_TRUE(same5);
691
692 // new with empty Function Constructor
693 Local<FunctionRef> son1 = FunctionRef::New(vm_, FunctionCallback, nullptr);
694 son1->Inherit(vm_, mapLocal);
695 JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(son1));
696 ASSERT_TRUE(son1Handle->HasFunctionPrototype());
697 }
698
HWTEST_F_L0(JSNApiTests,InheritPrototype_002)699 HWTEST_F_L0(JSNApiTests, InheritPrototype_002)
700 {
701 LocalScope scope(vm_);
702 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
703 // new with Builtins::weakSet Prototype
704 JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction();
705 Local<FunctionRef> weakSetLocal = JSNApiHelper::ToLocal<FunctionRef>(weakSet);
706 // new with Builtins::weakMap Prototype
707 JSHandle<JSTaggedValue> weakMap = env->GetBuiltinsWeakMapFunction();
708 Local<FunctionRef> weakMapLocal = JSNApiHelper::ToLocal<FunctionRef>(weakMap);
709
710 weakMapLocal->Inherit(vm_, weakSetLocal);
711
712 auto factory = vm_->GetFactory();
713 JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromCanBeCompressString("property1").GetTaggedValue());
714 JSHandle<JSTaggedValue> func = env->GetArrayFunction();
715 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
716 bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(weakMap), property1String, desc1);
717 ASSERT_TRUE(success1);
718
719 JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(weakMapLocal);
720 JSHandle<JSObject> sonObj =
721 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle);
722
723 JSHandle<JSTaggedValue> fatherHandle = JSNApiHelper::ToJSHandle(weakSetLocal);
724 JSHandle<JSObject> fatherObj =
725 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(fatherHandle), fatherHandle);
726
727 JSHandle<JSTaggedValue> sonMethod =
728 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(sonObj), property1String);
729 JSHandle<JSTaggedValue> fatherMethod =
730 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(fatherObj), property1String);
731 bool same = JSTaggedValue::SameValue(sonMethod, fatherMethod);
732 ASSERT_TRUE(same);
733 }
734
HWTEST_F_L0(JSNApiTests,InheritPrototype_003)735 HWTEST_F_L0(JSNApiTests, InheritPrototype_003)
736 {
737 LocalScope scope(vm_);
738 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
739 auto factory = vm_->GetFactory();
740
741 JSMethod *invokeSelf =
742 vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf));
743 // father type
744 JSHandle<JSHClass> protoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
745 JSHandle<JSFunction> protoFunc = factory->NewJSFunctionByDynClass(invokeSelf, protoDynclass);
746 Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc));
747 // son type
748 JSHandle<JSHClass> noProtoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
749 JSHandle<JSFunction> noProtoFunc = factory->NewJSFunctionByDynClass(invokeSelf, noProtoDynclass);
750 Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc));
751
752 JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
753 EXPECT_FALSE(sonHandle->HasFunctionPrototype());
754
755 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
756 PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString);
757 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), defaultString, desc);
758
759 noProtoLocal->Inherit(vm_, protoLocal);
760 JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
761 EXPECT_TRUE(son1Handle->HasFunctionPrototype());
762
763 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), defaultString);
764 EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res.GetValue()), true);
765
766 JSHandle<JSTaggedValue> propertyString(thread_, factory->NewFromCanBeCompressString("property").GetTaggedValue());
767 JSHandle<JSTaggedValue> func = env->GetArrayFunction();
768 PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
769 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), propertyString, desc1);
770 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), propertyString);
771 EXPECT_EQ(JSTaggedValue::SameValue(func, res1.GetValue()), true);
772 }
773
HWTEST_F_L0(JSNApiTests,InheritPrototype_004)774 HWTEST_F_L0(JSNApiTests, InheritPrototype_004)
775 {
776 LocalScope scope(vm_);
777 JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
778 auto factory = vm_->GetFactory();
779
780 JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction();
781 JSHandle<JSTaggedValue> deleteString(factory->NewFromCanBeCompressString("delete"));
782 JSHandle<JSTaggedValue> addString(factory->NewFromCanBeCompressString("add"));
783 JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
784 JSHandle<JSTaggedValue> deleteMethod = JSObject::GetMethod(thread_, weakSet, deleteString);
785 JSHandle<JSTaggedValue> addMethod = JSObject::GetMethod(thread_, weakSet, addString);
786
787 JSMethod *invokeSelf =
788 vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf));
789 JSMethod *ctor = vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionConstructor));
790
791 JSHandle<JSHClass> protoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
792 JSHandle<JSFunction> funcFuncPrototype = factory->NewJSFunctionByDynClass(invokeSelf, protoDynclass);
793 // add method in funcPrototype
794 PropertyDescriptor desc = PropertyDescriptor(thread_, deleteMethod);
795 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(funcFuncPrototype), deleteString, desc);
796 JSHandle<JSTaggedValue> funcFuncPrototypeValue(funcFuncPrototype);
797
798 JSHandle<JSHClass> funcFuncProtoIntanceDynclass =
799 factory->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncPrototypeValue);
800 // new with NewJSFunctionByDynClass::function DynClass
801 JSHandle<JSFunction> protoFunc =
802 factory->NewJSFunctionByDynClass(ctor, funcFuncProtoIntanceDynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
803 EXPECT_TRUE(*protoFunc != nullptr);
804 // add method in funcnction
805 PropertyDescriptor desc1 = PropertyDescriptor(thread_, addMethod);
806 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), addString, desc1);
807 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), deleteString, desc);
808 // father type
809 Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc));
810
811 JSHandle<JSHClass> noProtoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
812 JSHandle<JSFunction> funcFuncNoProtoPrototype = factory->NewJSFunctionByDynClass(invokeSelf, noProtoDynclass);
813 JSHandle<JSTaggedValue> funcFuncNoProtoPrototypeValue(funcFuncNoProtoPrototype);
814
815 JSHandle<JSHClass> funcFuncNoProtoProtoIntanceDynclass =
816 factory->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncNoProtoPrototypeValue);
817 // new with NewJSFunctionByDynClass::function DynClass
818 JSHandle<JSFunction> noProtoFunc =
819 factory->NewJSFunctionByDynClass(ctor, funcFuncNoProtoProtoIntanceDynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
820 EXPECT_TRUE(*noProtoFunc != nullptr);
821 // set property that has same key with fater type
822 PropertyDescriptor desc2 = PropertyDescriptor(thread_, defaultString);
823 JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(noProtoFunc), addString, desc2);
824 // son type
825 Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc));
826
827 noProtoLocal->Inherit(vm_, protoLocal);
828
829 JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
830 OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), deleteString);
831 EXPECT_EQ(JSTaggedValue::SameValue(deleteMethod, res.GetValue()), true);
832 // test if the property value changed after inherit
833 OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), addString);
834 EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res1.GetValue()), true);
835 }
836
HWTEST_F_L0(JSNApiTests,ClassFunction)837 HWTEST_F_L0(JSNApiTests, ClassFunction)
838 {
839 LocalScope scope(vm_);
840 Local<FunctionRef> cls = FunctionRef::NewClassFunction(vm_, nullptr, nullptr, nullptr);
841
842 JSHandle<JSTaggedValue> clsObj = JSNApiHelper::ToJSHandle(Local<JSValueRef>(cls));
843 ASSERT_TRUE(clsObj->IsClassConstructor());
844
845 JSTaggedValue accessor = JSHandle<JSFunction>(clsObj)->GetPropertyInlinedProps(
846 JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX);
847 ASSERT_TRUE(accessor.IsInternalAccessor());
848 }
849 } // namespace panda::test