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