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 "native_engine/native_value.h"
17#include "napi/native_api.h"
18#include "napi/native_node_api.h"
19#include "test.h"
20#include "test_timer.h"
21#include "../timer.h"
22#include "tools/log.h"
23
24using namespace Commonlibrary::Concurrent::Common;
25using namespace OHOS::JsSysModule;
26
27#define ASSERT_CHECK_CALL(call)   \
28    {                             \
29        ASSERT_EQ(call, napi_ok); \
30    }
31
32#define ASSERT_CHECK_VALUE_TYPE(env, value, type)               \
33    {                                                           \
34        napi_valuetype valueType = napi_undefined;              \
35        ASSERT_TRUE((value) != nullptr);                        \
36        ASSERT_CHECK_CALL(napi_typeof(env, value, &valueType)); \
37        ASSERT_EQ(valueType, type);                             \
38    }
39
40napi_value TimerCallback(napi_env env, napi_callback_info info)
41{
42    if (info == nullptr) {
43        HILOG_ERROR("TimerCallback, Invalid input info.");
44    }
45    return nullptr;
46}
47
48napi_value ThrowingCallback(napi_env env, napi_callback_info info)
49{
50    napi_value errorMessage;
51    napi_value error;
52    napi_create_string_utf8(env, "An error occurred!", NAPI_AUTO_LENGTH, &errorMessage);
53    napi_create_error(env, nullptr, errorMessage, &error);
54    napi_throw(env, error);
55    return nullptr;
56}
57
58/* @tc.name: Init
59 * @tc.desc: Test.
60 * @tc.type: FUNC
61 */
62HWTEST_F(NativeEngineTest, TimerTest001, testing::ext::TestSize.Level0)
63{
64    napi_env env = (napi_env)engine_;
65    bool res0 = Timer::RegisterTime(env);
66    ASSERT_TRUE(res0);
67    bool res1 = Timer::RegisterTime(nullptr);
68    ASSERT_TRUE(!res1);
69}
70
71/* @tc.name: settimeout
72 * @tc.desc: Test.
73 * @tc.type: FUNC
74 */
75HWTEST_F(NativeEngineTest, TimerTest002, testing::ext::TestSize.Level0)
76{
77    napi_env env = (napi_env)engine_;
78    size_t argc = 0;
79    napi_value argv0[] = {nullptr}; // no args has exception
80    napi_value cb = nullptr;
81    napi_create_function(env, "setInterval", NAPI_AUTO_LENGTH, TimerTest::SetInterval, nullptr, &cb);
82    napi_value res = nullptr;
83    napi_call_function(env, nullptr, cb, argc, argv0, &res);
84    ASSERT_TRUE(res == nullptr);
85    bool res0 = 0;
86    napi_is_exception_pending(env, &res0);
87    ASSERT_TRUE(res0);
88    napi_value exception = nullptr;
89    napi_get_and_clear_last_exception(env, &exception);
90}
91
92/* @tc.name: settimeout
93 * @tc.desc: Test.
94 * @tc.type: FUNC
95 */
96HWTEST_F(NativeEngineTest, TimerTest003, testing::ext::TestSize.Level0)
97{
98    napi_env env = (napi_env)engine_;
99    size_t argc = 2;
100    napi_value nativeMessage0 = nullptr;
101    napi_create_uint32(env, 5, &nativeMessage0); // Random number
102    napi_value nativeMessage1 = nullptr;
103    napi_create_uint32(env, 50, &nativeMessage1); // Random number
104    napi_value argv[] = {nativeMessage0, nativeMessage1};
105    napi_value cb = nullptr;
106    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb); // uncallable
107    napi_value tId = nullptr;
108    napi_call_function(env, nullptr, cb, argc, argv, &tId);
109    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_undefined);
110}
111
112/* @tc.name: settimeout/ClearTimer
113 * @tc.desc: Test.
114 * @tc.type: FUNC
115 */
116HWTEST_F(NativeEngineTest, TimerTest004, testing::ext::TestSize.Level0)
117{
118    napi_env env = (napi_env)engine_;
119    size_t argc = 2;
120    napi_value nativeMessage0 = nullptr;
121    napi_create_uint32(env, 50, &nativeMessage0); // Random number
122    napi_value nativeMessage1 = nullptr;
123    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
124    napi_value argv[] = {nativeMessage1, nativeMessage0};
125    napi_value setTimeoutCB = nullptr;
126    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &setTimeoutCB);
127    napi_value tId = nullptr;
128    napi_call_function(env, nullptr, setTimeoutCB, argc, argv, &tId);
129    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
130    napi_value argv1[] = {tId};
131    napi_value clearTimerCB = nullptr;
132    napi_create_function(env, "clearTimer", NAPI_AUTO_LENGTH, TimerTest::ClearTimer, nullptr, &clearTimerCB);
133    napi_value res = nullptr;
134    napi_call_function(env, nullptr, clearTimerCB, 1, argv1, &res);
135    ASSERT_CHECK_VALUE_TYPE(env, res, napi_undefined);
136}
137
138/* @tc.name: settimeout
139 * @tc.desc: Test.
140 * @tc.type: FUNC
141 */
142HWTEST_F(NativeEngineTest, TimerTest005, testing::ext::TestSize.Level0)
143{
144    napi_env env = (napi_env)engine_;
145    size_t argc = 2;
146    int32_t number = -50.0; // Random number
147    napi_value nativeMessage0 = nullptr;
148    napi_create_int32(env, number, &nativeMessage0);
149    napi_value nativeMessage1 = nullptr;
150    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
151    napi_value argv[] = {nativeMessage1, nativeMessage0};
152    napi_value cb = nullptr;
153    napi_create_function(env, "setTimerout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb);
154    napi_value tId = nullptr;
155    napi_call_function(env, nullptr, cb, argc, argv, &tId);
156    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
157}
158
159/* @tc.name: settimeout
160 * @tc.desc: Test.
161 * @tc.type: FUNC
162 */
163HWTEST_F(NativeEngineTest, TimerTest006, testing::ext::TestSize.Level0)
164{
165    napi_env env = (napi_env)engine_;
166    size_t argc = 2;
167    napi_value nativeMessage0 = nullptr;
168    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage0);
169    std::string message = "50";
170    napi_value nativeMessage1 = nullptr;
171    napi_create_string_utf8(env, message.c_str(), message.length(), &nativeMessage1); // timeout is string
172    napi_value argv[] = {nativeMessage0, nativeMessage1};
173    napi_value cb = nullptr;
174    napi_create_function(env, "setTimerout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb);
175    napi_value tId = nullptr;
176    napi_call_function(env, nullptr, cb, argc, argv, &tId);
177    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
178}
179
180/* @tc.name: ClearTimer
181 * @tc.desc: Test.
182 * @tc.type: FUNC
183 */
184HWTEST_F(NativeEngineTest, TimerTest007, testing::ext::TestSize.Level0)
185{
186    napi_env env = (napi_env)engine_;
187    size_t argc = 0;
188    napi_value argv[] = {nullptr}; // no args
189    napi_value cb = nullptr;
190    napi_create_function(env, "clearTimer", NAPI_AUTO_LENGTH, TimerTest::ClearTimer, nullptr, &cb);
191    napi_value res = nullptr;
192    napi_call_function(env, nullptr, cb, argc, argv, &res);
193    ASSERT_CHECK_VALUE_TYPE(env, res, napi_undefined);
194}
195
196/* @tc.name: ClearTimer
197 * @tc.desc: Test.
198 * @tc.type: FUNC
199 */
200HWTEST_F(NativeEngineTest, TimerTest008, testing::ext::TestSize.Level0)
201{
202    napi_env env = (napi_env)engine_;
203    size_t argc = 1;
204    napi_value nativeMessage = nullptr;
205    std::string message = "50"; // Random number
206    napi_create_string_utf8(env, message.c_str(), message.length(), &nativeMessage);
207    napi_value argv[] = {nativeMessage};
208    napi_value cb = nullptr;
209    napi_create_function(env, "clearTimer", NAPI_AUTO_LENGTH, TimerTest::ClearTimer, nullptr, &cb);
210    napi_value res = nullptr;
211    napi_call_function(env, nullptr, cb, argc, argv, &res);
212    ASSERT_CHECK_VALUE_TYPE(env, res, napi_undefined);
213}
214
215/* @tc.name: ClearTimer
216 * @tc.desc: Test.
217 * @tc.type: FUNC
218 */
219HWTEST_F(NativeEngineTest, TimerTest009, testing::ext::TestSize.Level0)
220{
221    napi_env env = (napi_env)engine_;
222    size_t argc = 1;
223    napi_value cb = nullptr;
224    napi_value inputId = nullptr;
225    napi_create_uint32(env, 50, &inputId); // Random number
226    napi_value argv[] = { inputId }; // timerId is inexistent
227    napi_create_function(env, "clearTimer", NAPI_AUTO_LENGTH, TimerTest::ClearTimer, nullptr, &cb);
228    napi_value res = nullptr;
229    napi_call_function(env, nullptr, cb, argc, argv, &res);
230    ASSERT_CHECK_VALUE_TYPE(env, res, napi_undefined);
231}
232
233/* @tc.name: setinteval
234 * @tc.desc: Test.
235 * @tc.type: FUNC
236 */
237HWTEST_F(NativeEngineTest, TimerTest010, testing::ext::TestSize.Level0)
238{
239    napi_env env = (napi_env)engine_;
240    size_t argc = 2;
241    napi_value nativeMessage0 = nullptr;
242    napi_create_uint32(env, 5, &nativeMessage0); // Random number
243    napi_value nativeMessage1 = nullptr;
244    napi_create_uint32(env, 50, &nativeMessage1); // Random number
245    napi_value argv1[] = {nativeMessage0, nativeMessage1};
246    napi_value cb1 = nullptr;
247    napi_create_function(env, "setInterval", NAPI_AUTO_LENGTH, TimerTest::SetInterval, nullptr, &cb1); // uncallable
248    napi_value tId1 = nullptr;
249    napi_call_function(env, nullptr, cb1, argc, argv1, &tId1);
250    ASSERT_CHECK_VALUE_TYPE(env, tId1, napi_undefined);
251    napi_value nativeMessage2 = nullptr;
252    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage2);
253    napi_value argv2[] = {nativeMessage2, nativeMessage1};
254    napi_value tId2 = nullptr;
255    napi_value cb2 = nullptr;
256    napi_create_function(env, "setInterval", NAPI_AUTO_LENGTH, TimerTest::SetInterval, nullptr, &cb2);
257    napi_call_function(env, nullptr, cb2, argc, argv2, &tId2);
258    ASSERT_CHECK_VALUE_TYPE(env, tId2, napi_number);
259    int32_t number = -50.0; // Random number
260    napi_value nativeMessage3 = nullptr;
261    napi_create_int32(env, number, &nativeMessage3);
262    napi_value argv3[] = {nativeMessage2, nativeMessage3};
263    napi_value tId3 = nullptr;
264    napi_value cb3 = nullptr;
265    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb3);
266    napi_call_function(env, nullptr, cb3, argc, argv3, &tId3);
267    ASSERT_CHECK_VALUE_TYPE(env, tId3, napi_number);
268    std::string message = "50"; // Random number
269    napi_value nativeMessage4 = nullptr;
270    napi_create_string_utf8(env, message.c_str(), message.length(), &nativeMessage4);
271    napi_value argv4[] = {nativeMessage2, nativeMessage4};
272    napi_value tId4 = nullptr;
273    napi_value cb4 = nullptr;
274    napi_create_function(env, "setInterval", NAPI_AUTO_LENGTH, TimerTest::SetInterval, nullptr, &cb4);
275    napi_call_function(env, nullptr, cb4, argc, argv4, &tId4);
276    ASSERT_CHECK_VALUE_TYPE(env, tId4, napi_number);
277
278    bool res0 = Timer::HasTimer(env);
279    ASSERT_TRUE(res0);
280    Timer::ClearEnvironmentTimer(env);
281    bool res1 = Timer::HasTimer(env);
282    ASSERT_TRUE(!res1);
283}
284
285/* @tc.name: settimeout
286 * @tc.desc: Test.
287 * @tc.type: FUNC
288 */
289HWTEST_F(NativeEngineTest, TimerTest011, testing::ext::TestSize.Level0)
290{
291    napi_env env = (napi_env)engine_;
292    size_t argc = 1;  // argc = 1, timeout = 0
293
294    napi_value tId = nullptr;
295    napi_value cb = nullptr;
296    napi_value nativeMessage1 = nullptr;
297    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
298    napi_value argv[] = {nativeMessage1};
299    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb);
300    napi_call_function(env, nullptr, cb, argc, argv, &tId);
301    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
302}
303
304/* @tc.name: settimeout
305 * @tc.desc: Test: callbackArgc > 0
306 * @tc.type: FUNC
307 */
308HWTEST_F(NativeEngineTest, TimerTest012, testing::ext::TestSize.Level0)
309{
310    napi_env env = (napi_env)engine_;
311    size_t argc = 3;
312    napi_value tId = nullptr;
313    napi_value cb = nullptr;
314    napi_value nativeMessage0 = nullptr;
315    napi_create_uint32(env, 50, &nativeMessage0); // Random number
316    napi_value nativeMessage2 = nullptr;
317    napi_create_uint32(env, 50, &nativeMessage2); // Random number
318    napi_value nativeMessage1 = nullptr;
319    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
320    napi_value argv[] = {nativeMessage1, nativeMessage0, nativeMessage2};
321    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &cb);
322    napi_call_function(env, nullptr, cb, argc, argv, &tId);
323    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
324}
325
326/* @tc.name: DeleteTimer
327 * @tc.desc: Test.
328 * @tc.type: FUNC
329 */
330HWTEST_F(NativeEngineTest, TimerTest013, testing::ext::TestSize.Level0)
331{
332    std::map<uint32_t, TimerCallbackInfo*>& table = TimerTest::create_timerTable();
333    napi_env env = (napi_env)engine_;
334    uint32_t tId = 1;
335    int32_t timeout = 1000;
336    napi_ref callback = nullptr;
337    bool repeat = false;
338    size_t argc = 0;
339    napi_ref* argv = nullptr;
340    TimerCallbackInfo* callbackInfo = new TimerCallbackInfo(env, tId, timeout, callback, repeat, argc, argv);
341    table[tId] = callbackInfo;
342    TimerTest::DeleteTimer(tId, callbackInfo);
343    ASSERT_TRUE(table.find(tId) == table.end());
344}
345
346/* @tc.name: Settimeout
347 * @tc.desc: Test.
348 * @tc.type: FUNC
349 */
350HWTEST_F(NativeEngineTest, TimerTest014, testing::ext::TestSize.Level0)
351{
352    napi_env env = (napi_env)engine_;
353    size_t argc = 2;
354    napi_value nativeMessage0 = nullptr;
355    napi_create_uint32(env, 50, &nativeMessage0); // Random number
356    napi_value nativeMessage1 = nullptr;
357    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
358    napi_value argv[] = {nativeMessage1, nativeMessage0};
359    napi_value setTimeoutCB = nullptr;
360    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &setTimeoutCB);
361    napi_value tId = nullptr;
362    napi_call_function(env, nullptr, setTimeoutCB, argc, argv, &tId);
363    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
364    napi_env* env2 = new napi_env;
365    napi_create_runtime(env, env2);
366    napi_value argv1[] = {tId};
367    napi_value clearTimerCB = nullptr;
368    napi_create_function(*env2, "clearTimer", NAPI_AUTO_LENGTH, TimerTest::ClearTimer, nullptr, &clearTimerCB);
369    napi_value res = nullptr;
370    napi_call_function(*env2, nullptr, clearTimerCB, 1, argv1, &res);
371    ASSERT_CHECK_VALUE_TYPE(*env2, res, napi_undefined);
372}
373
374/* @tc.name: ClearEnvironmentTimer
375 * @tc.desc: Test.
376 * @tc.type: FUNC
377 */
378HWTEST_F(NativeEngineTest, TimerTest015, testing::ext::TestSize.Level0)
379{
380    uv_timer_t* handle = new uv_timer_t;
381    handle->data = nullptr;
382    TimerTest::TimerCallback(handle);
383
384    napi_env env = (napi_env)engine_;
385    size_t argc = 2;
386    napi_value nativeMessage0 = nullptr;
387    napi_create_uint32(env, 50, &nativeMessage0); // Random number
388    napi_value nativeMessage1 = nullptr;
389    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
390    napi_value argv[] = {nativeMessage1, nativeMessage0};
391    napi_value setTimeoutCB = nullptr;
392    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &setTimeoutCB);
393    napi_value tId = nullptr;
394    napi_call_function(env, nullptr, setTimeoutCB, argc, argv, &tId);
395    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
396    napi_env* env2 = new napi_env;
397    napi_create_runtime(env, env2);
398    TimerTest::ClearEnvironmentTimer(*env2);
399    std::map<uint32_t, TimerCallbackInfo*>& table = TimerTest::create_timerTable();
400    ASSERT_TRUE(table.size() != 0);
401}
402
403/* @tc.name: settimeout
404 * @tc.desc: Test.
405 * @tc.type: FUNC
406 */
407HWTEST_F(NativeEngineTest, TimerTest016, testing::ext::TestSize.Level0)
408{
409    napi_env env = (napi_env)engine_;
410    napi_env* env2 = new napi_env;
411    napi_create_runtime(env, env2);
412    size_t argc = 2;
413    napi_value nativeMessage0 = nullptr;
414    napi_create_uint32(*env2, 50, &nativeMessage0); // Random number
415    napi_value nativeMessage1 = nullptr;
416    napi_create_function(*env2, "callback", NAPI_AUTO_LENGTH, TimerCallback, nullptr, &nativeMessage1);
417    napi_value argv[] = {nativeMessage1, nativeMessage0};
418    napi_value setTimeoutCB = nullptr;
419    napi_create_function(*env2, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &setTimeoutCB);
420    napi_value tId = nullptr;
421    napi_call_function(*env2, nullptr, setTimeoutCB, argc, argv, &tId);
422    ASSERT_CHECK_VALUE_TYPE(*env2, tId, napi_number);
423}
424
425/* @tc.name: settimeout
426 * @tc.desc: Test.
427 * @tc.type: FUNC
428 */
429HWTEST_F(NativeEngineTest, TimerTest017, testing::ext::TestSize.Level0)
430{
431    napi_env env = (napi_env)engine_;
432    napi_env env2 = nullptr;
433    uv_timer_t* handle = new uv_timer_t;
434    uint32_t tId2 = 1;
435    int32_t timeout = 1000;
436    napi_ref callback = nullptr;
437    bool repeat = false;
438    size_t argc2 = 0;
439    napi_ref* argv2 = nullptr;
440    handle->data = new TimerCallbackInfo(env, tId2, timeout, callback, repeat, argc2, argv2);
441    TimerCallbackInfo* callbackInfo = static_cast<TimerCallbackInfo*>(handle->data);
442    callbackInfo->env_ = env2;
443    TimerTest::TimerCallback(handle);
444
445    size_t argc = 2;
446    napi_value nativeMessage0 = nullptr;
447    napi_create_uint32(env, 50, &nativeMessage0); // Random number
448    napi_value nativeMessage1 = nullptr;
449    napi_create_function(env, "callback", NAPI_AUTO_LENGTH, ThrowingCallback, nullptr, &nativeMessage1);
450    napi_value argv[] = {nativeMessage1, nativeMessage0};
451    napi_value setTimeoutCB = nullptr;
452    napi_create_function(env, "setTimeout", NAPI_AUTO_LENGTH, TimerTest::SetTimeout, nullptr, &setTimeoutCB);
453    napi_value tId = nullptr;
454    napi_call_function(env, nullptr, setTimeoutCB, argc, argv, &tId);
455    ASSERT_CHECK_VALUE_TYPE(env, tId, napi_number);
456}