1 /*
2 * Copyright (c) 2021-2022 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 "napi/native_common.h"
17 #include "napi/native_api.h"
18 #include "napi/native_node_api.h"
19 #include "securec.h"
20 #include "test.h"
21 #include "test_common.h"
22 #include "utils/log.h"
23 #ifdef FOR_JERRYSCRIPT_TEST
24 #include "jerryscript-core.h"
25 #endif
26
27 static constexpr int32_t NAPI_UT_BUFFER_SIZE = 64;
28
29 class NapiExtTest : public NativeEngineTest {
30 public:
SetUpTestCase()31 static void SetUpTestCase()
32 {
33 GTEST_LOG_(INFO) << "NapiExtTest SetUpTestCase";
34 }
35
TearDownTestCase()36 static void TearDownTestCase()
37 {
38 GTEST_LOG_(INFO) << "NapiExtTest TearDownTestCase";
39 }
40
SetUp()41 void SetUp() override {}
TearDown()42 void TearDown() override {}
43 };
44
45 /**
46 * @tc.name: UndefinedTest
47 * @tc.desc: Test undefined type.
48 * @tc.type: FUNC
49 */
50 HWTEST_F(NapiExtTest, CreateBufferTest001, testing::ext::TestSize.Level1)
51 {
52 napi_env env = (napi_env)engine_;
53
54 napi_value buffer = nullptr;
55 void* bufferPtr = nullptr;
56 size_t bufferSize = NAPI_UT_BUFFER_SIZE;
57 napi_create_buffer(env, bufferSize, &bufferPtr, &buffer);
58 void* tmpBufferPtr = nullptr;
59 size_t bufferLength = 0;
60 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength);
61
62 ASSERT_EQ(bufferPtr, tmpBufferPtr);
63 ASSERT_EQ(bufferSize, bufferLength);
64 }
65
66 HWTEST_F(NapiExtTest, CreateBufferTest003, testing::ext::TestSize.Level1)
67 {
68 napi_env env = (napi_env)engine_;
69
70 napi_value buffer = nullptr;
71 void* bufferPtr = nullptr;
72 const char bufferdata[] = "for test";
73 const char* data = bufferdata;
74 size_t bufferSize = NAPI_UT_BUFFER_SIZE;
75 napi_create_buffer_copy(env, bufferSize, data, &bufferPtr, &buffer);
76
77 void* tmpBufferPtr = nullptr;
78 size_t bufferLength = 0;
79 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength);
80
81 ASSERT_EQ(bufferPtr, tmpBufferPtr);
82 ASSERT_EQ(bufferSize, bufferLength);
83 ASSERT_EQ(0, memcmp(bufferdata, bufferPtr, bufferSize));
84 }
85
86 HWTEST_F(NapiExtTest, CreateBufferTest005, testing::ext::TestSize.Level1)
87 {
88 napi_env env = (napi_env)engine_;
89
90 napi_value buffer = nullptr;
91 char testStr[] = "test";
92 void* bufferPtr = testStr;
93
94 size_t bufferSize = NAPI_UT_BUFFER_SIZE;
95 napi_create_external_buffer(
__anonf6d3c2380102(napi_env env, void* data, void* hint) 96 env, bufferSize, bufferPtr, [](napi_env env, void* data, void* hint) {}, (void*)testStr, &buffer);
97
98 void* tmpBufferPtr = nullptr;
99 size_t bufferLength = 0;
100 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength);
101 bool isBuffer = false;
102 napi_is_buffer(env, buffer, &isBuffer);
103
104 ASSERT_EQ(bufferSize, bufferLength);
105 }
106
107 HWTEST_F(NapiExtTest, IsBufferTest001, testing::ext::TestSize.Level1)
108 {
109 napi_env env = (napi_env)engine_;
110
111 napi_value buffer = nullptr;
112 void* bufferPtr = nullptr;
113 size_t bufferSize = NAPI_UT_BUFFER_SIZE;
114 bool isBuffer = false;
115
116 napi_create_buffer(env, bufferSize, &bufferPtr, &buffer);
117
118 void* tmpBufferPtr = nullptr;
119 size_t bufferLength = 0;
120 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength);
121 napi_is_buffer(env, buffer, &isBuffer);
122
123 ASSERT_TRUE(isBuffer);
124 }
125
126 HWTEST_F(NapiExtTest, IsBufferTest002, testing::ext::TestSize.Level1)
127 {
128 napi_env env = (napi_env)engine_;
129
130 napi_value buffer = nullptr;
131 void* bufferPtr = nullptr;
132 size_t bufferSize = -1;
133 bool isBuffer = false;
134
135 napi_create_buffer(env, bufferSize, &bufferPtr, &buffer);
136
137 void* tmpBufferPtr = nullptr;
138 size_t bufferLength = 0;
139 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength);
140 napi_is_buffer(env, buffer, &isBuffer);
141
142 ASSERT_EQ(isBuffer, false);
143 }
144
145 #if (defined(FOR_JERRYSCRIPT_TEST)) && (JERRY_API_MINOR_VERSION <= 3)
146 // jerryscript 2.3 do nothing
147 #else
148 // jerryscript 2.4 or quickjs or V8
149
150 /**
151 * @tc.name: BigIntTest
152 * @tc.desc: Test number type.
153 * @tc.type: FUNC
154 */
155 HWTEST_F(NapiExtTest, BigIntTest001, testing::ext::TestSize.Level1)
156 {
157 napi_env env = (napi_env)engine_;
158 // uint64
159 {
160 uint64_t testValue = UINT64_MAX;
161 napi_value result = nullptr;
162 bool flag = false;
163 ASSERT_CHECK_CALL(napi_create_bigint_uint64(env, testValue, &result));
164 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
165
166 uint64_t resultValue = 0;
167 ASSERT_CHECK_CALL(napi_get_value_bigint_uint64(env, result, &resultValue, &flag));
168 ASSERT_EQ(resultValue, UINT64_MAX);
169 ASSERT_TRUE(flag);
170 }
171 {
172 uint64_t testValue = 0xffffffffffffffff;
173 napi_value result = nullptr;
174 ASSERT_CHECK_CALL(napi_create_bigint_uint64(env, testValue, &result));
175 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
176 bool flag = false;
177 uint64_t resultValue = 0;
178 ASSERT_CHECK_CALL(napi_get_value_bigint_uint64(env, result, &resultValue, &flag));
179 ASSERT_EQ(resultValue, testValue);
180 ASSERT_TRUE(flag);
181 }
182 {
183 uint64_t testValue = 9007199254740991;
184 napi_value result = nullptr;
185 ASSERT_CHECK_CALL(napi_create_bigint_uint64(env, testValue, &result));
186 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
187 bool flag = false;
188 uint64_t resultValue = 0;
189 ASSERT_CHECK_CALL(napi_get_value_bigint_uint64(env, result, &resultValue, &flag));
190 ASSERT_EQ(resultValue, testValue);
191 ASSERT_TRUE(flag);
192 }
193 }
194
195 HWTEST_F(NapiExtTest, BigIntTest002, testing::ext::TestSize.Level1)
196 {
197 napi_env env = (napi_env)engine_;
198 // int64
199 {
200 int64_t testValue = INT64_MAX;
201 napi_value result = nullptr;
202 bool flag = false;
203 ASSERT_CHECK_CALL(napi_create_bigint_int64(env, testValue, &result));
204 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
205
206 int64_t resultValue = 0;
207 ASSERT_CHECK_CALL(napi_get_value_bigint_int64(env, result, &resultValue, &flag));
208 ASSERT_EQ(resultValue, INT64_MAX);
209 ASSERT_TRUE(flag);
210 }
211 {
212 int64_t testValue = 9007199254740991;
213 napi_value result = nullptr;
214 ASSERT_CHECK_CALL(napi_create_bigint_int64(env, testValue, &result));
215 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
216 bool flag = false;
217 int64_t resultValue = 0;
218 ASSERT_CHECK_CALL(napi_get_value_bigint_int64(env, result, &resultValue, &flag));
219 ASSERT_EQ(resultValue, testValue);
220 ASSERT_TRUE(flag);
221 }
222 {
223 int64_t testValue = -1;
224 napi_value result = nullptr;
225 ASSERT_CHECK_CALL(napi_create_bigint_int64(env, testValue, &result));
226 ASSERT_CHECK_VALUE_TYPE(env, result, napi_bigint);
227 bool flag = false;
228 int64_t resultValue = 0;
229 ASSERT_CHECK_CALL(napi_get_value_bigint_int64(env, result, &resultValue, &flag));
230 ASSERT_EQ(resultValue, testValue);
231 ASSERT_TRUE(flag);
232 }
233 }
234
235 HWTEST_F(NapiExtTest, BigIntWordsTest001, testing::ext::TestSize.Level1)
236 {
237 napi_env env = (napi_env)engine_;
238 int signBit = 0;
239 size_t wordCount = 4;
240 uint64_t words[] = { 0xFFFFFFFFFFFFFFFF, 34ULL, 56ULL, 0xFFFFFFFFFFFFFFFF };
241 uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL };
242 napi_value result = nullptr;
243 ASSERT_CHECK_CALL(napi_create_bigint_words(env, signBit, wordCount, words, &result));
244
245 ASSERT_CHECK_CALL(napi_get_value_bigint_words(env, result, &signBit, &wordCount, wordsOut));
246
247 ASSERT_EQ(signBit, 0);
248 ASSERT_EQ(wordCount, 4);
249 ASSERT_EQ(words[0], wordsOut[0]);
250 ASSERT_EQ(words[1], wordsOut[1]);
251 ASSERT_EQ(words[2], wordsOut[2]);
252 ASSERT_EQ(words[3], wordsOut[3]);
253 }
254
255 HWTEST_F(NapiExtTest, BigIntWordsTest002, testing::ext::TestSize.Level1)
256 {
257 napi_env env = (napi_env)engine_;
258 int signBit = 0;
259 size_t wordCount = 5;
260 uint64_t words[] = { 12ULL, 34ULL, 56ULL, 78ULL, 90ULL };
261 uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL, 0ULL };
262 napi_value result = nullptr;
263 ASSERT_CHECK_CALL(napi_create_bigint_words(env, signBit, wordCount, words, &result));
264
265 ASSERT_CHECK_CALL(napi_get_value_bigint_words(env, result, &signBit, &wordCount, wordsOut));
266
267 ASSERT_EQ(signBit, 0);
268 ASSERT_EQ(wordCount, 5);
269 for (size_t i = 0; i < wordCount; i++) {
270 ASSERT_EQ(words[i], wordsOut[i]);
271 }
272 }
273
274 HWTEST_F(NapiExtTest, BigIntWordsTest003, testing::ext::TestSize.Level1)
275 {
276 napi_env env = (napi_env)engine_;
277 int signBit = 1;
278 size_t wordCount = 4;
279 uint64_t words[] = { 0xFFFFFFFFFFFFFFFF, 34ULL, 56ULL, 0xFFFFFFFFFFFFFFFF };
280 uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL };
281 napi_value result = nullptr;
282 ASSERT_CHECK_CALL(napi_create_bigint_words(env, signBit, wordCount, words, &result));
283
284 ASSERT_CHECK_CALL(napi_get_value_bigint_words(env, result, &signBit, &wordCount, wordsOut));
285
286 ASSERT_EQ(signBit, 1);
287 ASSERT_EQ(wordCount, 4);
288 ASSERT_EQ(words[0], wordsOut[0]);
289 ASSERT_EQ(words[1], wordsOut[1]);
290 ASSERT_EQ(words[2], wordsOut[2]);
291 ASSERT_EQ(words[3], wordsOut[3]);
292 }
293
294 HWTEST_F(NapiExtTest, BigIntWordsTest004, testing::ext::TestSize.Level1)
295 {
296 napi_env env = (napi_env)engine_;
297 int signBit = 1;
298 size_t wordCount = 5;
299 uint64_t words[] = { 12ULL, 34ULL, 56ULL, 78ULL, 0x000000FF98765432 };
300 uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL, 0ULL };
301 napi_value result = nullptr;
302 ASSERT_CHECK_CALL(napi_create_bigint_words(env, signBit, wordCount, words, &result));
303
304 ASSERT_CHECK_CALL(napi_get_value_bigint_words(env, result, &signBit, &wordCount, wordsOut));
305
306 ASSERT_EQ(signBit, 1);
307 ASSERT_EQ(wordCount, 5);
308 for (size_t i = 0; i < wordCount; i++) {
309 ASSERT_EQ(words[i], wordsOut[i]);
310 }
311 }
312
313 HWTEST_F(NapiExtTest, TagObjectTest001, testing::ext::TestSize.Level1)
314 {
315 napi_env env = (napi_env)engine_;
316 napi_value object = nullptr;
317 const napi_type_tag typeTag = { 0xFFFFFFFFFFFFFFFF, 34ULL };
318
319 ASSERT_CHECK_CALL(napi_create_object(env, &object));
320
321 ASSERT_CHECK_CALL(napi_type_tag_object(env, object, &typeTag));
322
323 bool checkResult = false;
324
325 ASSERT_CHECK_CALL(napi_check_object_type_tag(env, object, &typeTag, &checkResult));
326 ASSERT_TRUE(checkResult);
327 }
328 #endif
329
330 HWTEST_F(NapiExtTest, GetDateTest001, testing::ext::TestSize.Level1)
331 {
332 napi_env env = (napi_env)engine_;
333 napi_value createResult = nullptr;
334 double time = 202110181203150;
335
336 ASSERT_CHECK_CALL(napi_create_date(env, time, &createResult));
337
338 double getTime = false;
339
340 ASSERT_CHECK_CALL(napi_get_date_value(env, createResult, &getTime));
341 bool result = false;
342 if (time == getTime) {
343 result = true;
344 }
345 ASSERT_TRUE(result);
346 }
347
348 HWTEST_F(NapiExtTest, IsDateTest001, testing::ext::TestSize.Level1)
349 {
350 napi_env env = (napi_env)engine_;
351 napi_value createResult = nullptr;
352 double time = 202110181203150;
353
354 ASSERT_CHECK_CALL(napi_create_date(env, time, &createResult));
355
356 bool result = false;
357
358 ASSERT_CHECK_CALL(napi_is_date(env, createResult, &result));
359
360 ASSERT_TRUE(result);
361 }
362
363 /**
364 * @tc.name: ACE_napi_adjust_external_memory_test.
365 * @tc.desc: Test napi_adjust_external_memory.
366 * @tc.type: FUNC
367 */
368 HWTEST_F(NapiExtTest, AdjustExternalMemoryTest001, testing::ext::TestSize.Level1)
369 {
370 HILOG_INFO("%{public}s", "ACE_napi_adjust_external_memory_test start");
371 napi_env env = (napi_env)engine_;
372 int64_t changeInBytes = 32;
373 int64_t adjustedValue = 32;
374 napi_status ret = napi_adjust_external_memory(env, changeInBytes, &adjustedValue);
375 ASSERT_EQ(ret, napi_ok);
376 HILOG_INFO("%{public}s", "ACE_napi_adjust_external_memory_test end");
377 }
378
379 /**
380 * @tc.name: ACE_napi_async_init_Test.
381 * @tc.desc: Test napi_async_init, napi_async_destroy.
382 * @tc.type: FUNC
383 */
384 HWTEST_F(NapiExtTest, AsyncInitTest001, testing::ext::TestSize.Level1)
385 {
386 HILOG_INFO("ACE_napi_async_init_Test_001 start");
387
388 napi_env env = (napi_env)engine_;
389
390 napi_value resourceName;
391 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, "ACE_napi_async_init_Test_001",
392 NAPI_AUTO_LENGTH, &resourceName));
393
394 napi_async_context context = nullptr;
395 napi_status ret = napi_async_init(env, nullptr, resourceName, &context);
396 ASSERT_EQ(ret, napi_ok);
397 EXPECT_NE(context, nullptr);
398
399 ret = napi_async_destroy(env, context);
400 ASSERT_EQ(ret, napi_ok);
401
402 HILOG_INFO("ACE_napi_async_init_Test_001 end");
403 }
404
405 /**
406 * @tc.name: ACE_napi_open_callback_scope_Test
407 * @tc.desc: Test napi_open_callback_scope, napi_close_callback_scope.
408 * @tc.type: FUNC
409 */
410 HWTEST_F(NapiExtTest, OpenCallbackScopeTest001, testing::ext::TestSize.Level1)
411 {
412 HILOG_INFO("ACE_napi_open_callback_scope_Test_001 start");
413
414 napi_env env = (napi_env)engine_;
415
416 auto callbackScopeManager = engine_->GetCallbackScopeManager();
417 ASSERT_NE(callbackScopeManager, nullptr);
418
419 int openCallbackScopesBefore = callbackScopeManager->GetOpenCallbackScopes();
420 int asyncCallbackScopeDepthBefore = callbackScopeManager->GetAsyncCallbackScopeDepth();
421
422 napi_value resourceName;
423 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &resourceName));
424
425 napi_async_context context;
426 NAPI_CALL_RETURN_VOID(env, napi_async_init(env, nullptr, resourceName, &context));
427
428 napi_callback_scope scope = nullptr;
429 napi_status ret = napi_open_callback_scope(env, NULL, context, &scope);
430 EXPECT_EQ(ret, napi_ok);
431 EXPECT_NE(scope, nullptr);
432
433 int openCallbackScopes = callbackScopeManager->GetOpenCallbackScopes();
434 int asyncCallbackScopeDepth = callbackScopeManager->GetAsyncCallbackScopeDepth();
435 EXPECT_EQ(openCallbackScopes, (openCallbackScopesBefore + 1));
436 EXPECT_EQ(asyncCallbackScopeDepth, (asyncCallbackScopeDepthBefore + 1));
437
438 ret = napi_close_callback_scope(env, scope);
439 EXPECT_EQ(ret, napi_ok);
440
441 int openCallbackScopesAfter = callbackScopeManager->GetOpenCallbackScopes();
442 int asyncCallbackScopeDepthAfter = callbackScopeManager->GetAsyncCallbackScopeDepth();
443 EXPECT_EQ(openCallbackScopesAfter, openCallbackScopesBefore);
444 EXPECT_EQ(asyncCallbackScopeDepthAfter, asyncCallbackScopeDepthBefore);
445
446 NAPI_CALL_RETURN_VOID(env, napi_async_destroy(env, context));
447
448 HILOG_INFO("ACE_napi_open_callback_scope_Test_001 end");
449 }
450
451 /**
452 * @tc.name: ACE_napi_open_callback_scope_Test
453 * @tc.desc: Test napi_open_callback_scope, napi_close_callback_scope.
454 * @tc.type: FUNC
455 */
456 HWTEST_F(NapiExtTest, OpenCallbackScopeTest002, testing::ext::TestSize.Level1)
457 {
458 HILOG_INFO("ACE_napi_open_callback_scope_Test_002 start");
459
460 napi_env env = (napi_env)engine_;
461
462 auto callbackScopeManager = engine_->GetCallbackScopeManager();
463 ASSERT_NE(callbackScopeManager, nullptr);
464
465 int openCallbackScopesBefore = callbackScopeManager->GetOpenCallbackScopes();
466 int asyncCallbackScopeDepthBefore = callbackScopeManager->GetAsyncCallbackScopeDepth();
467
468 napi_value resourceName;
469 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &resourceName));
470
471 napi_async_context context;
472 NAPI_CALL_RETURN_VOID(env, napi_async_init(env, nullptr, resourceName, &context));
473
474 napi_callback_scope scope = nullptr;
475 napi_status ret = napi_open_callback_scope(env, NULL, context, &scope);
476 EXPECT_EQ(ret, napi_ok);
477 EXPECT_NE(scope, nullptr);
478
479 int openCallbackScopes1 = callbackScopeManager->GetOpenCallbackScopes();
480 int asyncCallbackScopeDepth1 = callbackScopeManager->GetAsyncCallbackScopeDepth();
481
482 // Open a internal callback scope
483 panda::Local<panda::ObjectRef> obj = panda::ObjectRef::New(env_->GetEcmaVm());
484 auto scope2 = callbackScopeManager->Open(engine_, obj, {0, 0});
485 int openCallbackScopes2 = callbackScopeManager->GetOpenCallbackScopes();
486 int asyncCallbackScopeDepth2 = callbackScopeManager->GetAsyncCallbackScopeDepth();
487
488 EXPECT_NE(scope2, nullptr);
489 EXPECT_EQ(openCallbackScopes2, openCallbackScopes1);
490 EXPECT_EQ(asyncCallbackScopeDepth2, (asyncCallbackScopeDepth1 + 1));
491
492 callbackScopeManager->Close(scope2);
493 obj->Delete(env_->GetEcmaVm(), obj);
494 int openCallbackScopes2After = callbackScopeManager->GetOpenCallbackScopes();
495 int asyncCallbackScopeDepth2After = callbackScopeManager->GetAsyncCallbackScopeDepth();
496
497 EXPECT_EQ(openCallbackScopes2After, openCallbackScopes1);
498 EXPECT_EQ(asyncCallbackScopeDepth2After, asyncCallbackScopeDepth1);
499
500 ret = napi_close_callback_scope(env, scope);
501 EXPECT_EQ(ret, napi_ok);
502
503 int openCallbackScopes1After = callbackScopeManager->GetOpenCallbackScopes();
504 int asyncCallbackScopeDepth1After = callbackScopeManager->GetAsyncCallbackScopeDepth();
505
506 EXPECT_EQ(openCallbackScopes1After, openCallbackScopesBefore);
507 EXPECT_EQ(asyncCallbackScopeDepth1After, asyncCallbackScopeDepthBefore);
508
509 NAPI_CALL_RETURN_VOID(env, napi_async_destroy(env, context));
510
511 HILOG_INFO("ACE_napi_open_callback_scope_Test_002 end");
512 }
513
TestFatalException(napi_env env,napi_callback_info info)514 static napi_value TestFatalException(napi_env env, napi_callback_info info)
515 {
516 napi_value err;
517 size_t argc = 1;
518
519 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &err, nullptr, nullptr));
520 NAPI_CALL(env, napi_fatal_exception(env, err));
521 return nullptr;
522 }
523
524 /**
525 * @tc.name: FatalException
526 * @tc.desc: Test FatalException Func.
527 * @tc.type: FUNC
528 */
529 HWTEST_F(NapiExtTest, FatalExceptionTest001, testing::ext::TestSize.Level1)
530 {
531 napi_env env = (napi_env)engine_;
532 ASSERT_EQ(TestFatalException(env, nullptr), nullptr);
533 }
534
535 HWTEST_F(NapiExtTest, AddFinalizerTest001, testing::ext::TestSize.Level1)
536 {
537 HILOG_INFO("add_finalizer_test_0100 start");
538 napi_env env = (napi_env)engine_;
539
540 napi_value object;
541 NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &object));
542
543 static bool testValue = false;
544 const char* testStr = "test";
545 napi_ref ref = nullptr;
546 napi_add_finalizer(
__anonf6d3c2380202(napi_env env, void* data, void* hint) 547 env, object, (void*)testStr, [](napi_env env, void* data, void* hint) {
548 testValue = true;
549 }, nullptr, &ref);
550
551 napi_delete_reference(env, ref);
552 ASSERT_TRUE(testValue);
553 HILOG_INFO("add_finalizer_test_0100 end");
554 }
555
556 typedef struct {
557 size_t value;
558 bool print;
559 napi_ref js_cb_ref;
560 } AddonData;
561
DeleteAddonData(napi_env env,void * raw_data,void * hint)562 static void DeleteAddonData(napi_env env, void* raw_data, void* hint)
563 {
564 AddonData* data = (AddonData*)raw_data;
565 if (data->print) {
566 printf("deleting addon data\n");
567 }
568 if (data->js_cb_ref != NULL) {
569 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, data->js_cb_ref));
570 }
571 free(data);
572 }
573
SetPrintOnDelete(napi_env env,napi_callback_info info)574 static napi_value SetPrintOnDelete(napi_env env, napi_callback_info info)
575 {
576 AddonData* data;
577 NAPI_CALL(env, napi_get_instance_data(env, (void**)&data));
578 data->print = true;
579 return NULL;
580 }
581
TestFinalizer(napi_env env,void * raw_data,void * hint)582 static void TestFinalizer(napi_env env, void* raw_data, void* hint)
583 {
584 (void)raw_data;
585 (void)hint;
586
587 AddonData* data;
588 napi_value jsResult;
589 NAPI_CALL_RETURN_VOID(env, napi_get_instance_data(env, (void**)&data));
590 napi_value js_cb, undefined;
591 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, data->js_cb_ref, &js_cb));
592 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
593 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, js_cb, 0, NULL, &jsResult));
594
595 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, data->js_cb_ref));
596 data->js_cb_ref = NULL;
597 }
598
ObjectWithFinalizer(napi_env env,napi_callback_info info)599 static napi_value ObjectWithFinalizer(napi_env env, napi_callback_info info)
600 {
601 HILOG_INFO("%{public}s", "start.");
602 AddonData* data;
603
604 napi_value result, js_cb;
605 size_t argc = 1;
606
607 auto func = [](napi_env env, napi_callback_info info) -> napi_value {
608 HILOG_INFO("%{public}s", "function called");
609 return nullptr;
610 };
611
612 napi_create_function(env, "testFunc", NAPI_AUTO_LENGTH, func, nullptr, &js_cb);
613
614 NAPI_CALL(env, napi_get_instance_data(env, (void**)&data));
615 NAPI_ASSERT(env, data->js_cb_ref == NULL, "reference must be NULL");
616 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &js_cb, NULL, NULL));
617 NAPI_CALL(env, napi_create_object(env, &result));
618 NAPI_CALL(env, napi_add_finalizer(env, result, NULL, TestFinalizer, NULL, NULL));
619 NAPI_CALL(env, napi_create_reference(env, js_cb, 1, &data->js_cb_ref));
620 HILOG_INFO("%{public}s", "end.");
621 return nullptr;
622 }
623
624 HWTEST_F(NapiExtTest, InstanceDataTest_001, testing::ext::TestSize.Level1)
625 {
626 napi_env env = (napi_env)engine_;
627 // Set instance data
628 AddonData* data = (AddonData*)malloc(sizeof(*data));
629 data->value = 41;
630 data->print = false;
631 data->js_cb_ref = NULL;
632 ASSERT_CHECK_CALL(napi_set_instance_data(env, data, DeleteAddonData, NULL));
633
634 // Test get instance data
635 AddonData* get_data = nullptr;
636 ASSERT_CHECK_CALL(napi_get_instance_data(env, (void**)&get_data));
637 ++get_data->value;
638 const size_t expectValue = 42;
639 ASSERT_EQ(get_data->value, expectValue);
640
641 // Test finalizer
642 SetPrintOnDelete(env, nullptr);
643 ObjectWithFinalizer(env, nullptr);
644 }
645