1 /*
2  * Copyright (C) 2024 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 <algorithm>
17 #include <cstdlib>
18 #include <string>
19 #include <thread>
20 
21 #include "component_test/component_test_proxy.h"
22 #include "component_test/test_config.h"
23 #include "interfaces/napi/kits/utils/napi_utils.h"
24 #include "js_component_test_component.h"
25 #include "js_component_test_matcher.h"
26 #include "js_component_test_tester.h"
27 #include "js_component_test_utils.h"
28 #include "napi/native_api.h"
29 #include "napi/native_node_api.h"
30 
31 #include "base/log/log.h"
32 #include "core/common/ace_engine.h"
33 
34 namespace OHOS::Ace::Napi {
35 
JSLoadComponentTestEntry(napi_env env, napi_callback_info info)36 static napi_value JSLoadComponentTestEntry(napi_env env, napi_callback_info info)
37 {
38     CHECK_COMPONENT_TEST_ENABLED();
39     size_t argc = ARG_COUNT_ONE;
40     napi_value argv = nullptr;
41     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr));
42 
43     COMPONENT_TEST_NAPI_ASSERT(env, argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID);
44     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv) == napi_function, ErrCode::RET_ERROR_PARAM_INVALID,
45         "Parameter entry is not of type function", NapiGetUndefined(env));
46     ComponentTestAsyncCtx* asyncContext = new (std::nothrow) ComponentTestAsyncCtx();
47     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(
48         env, asyncContext != nullptr, ErrCode::RET_ERR_FAILED, "Failed to create asyncContext.", NapiGetUndefined(env));
49 
50     napi_create_reference(env, argv, 1, &asyncContext->callbackRef);
51     napi_value resource = nullptr;
52     napi_create_string_utf8(env, "JSLoadComponentTestEntry", NAPI_AUTO_LENGTH, &resource);
53     napi_create_async_work(
54         env, nullptr, resource, [](napi_env env, void* data) {},
55         [](napi_env env, napi_status status, void* data) {
56             ComponentTestAsyncCtx* asyncContext = reinterpret_cast<ComponentTestAsyncCtx*>(data);
57             napi_value callback = nullptr;
58             napi_get_reference_value(env, asyncContext->callbackRef, &callback);
59             napi_call_function(env, nullptr, callback, 0, nullptr, &asyncContext->asyncResult);
60             napi_delete_reference(env, asyncContext->callbackRef);
61             napi_delete_async_work(env, asyncContext->asyncWork);
62             delete asyncContext;
63             asyncContext = nullptr;
64         },
65         (void*)asyncContext, &asyncContext->asyncWork);
66     napi_queue_async_work(env, asyncContext->asyncWork);
67     ComponentTest::ComponentTestManagerProxy::RequestContinuousIdleStatusNotification([]() {
68         LOGI("Previewer ComponentTest %{public}s Finished.",
69             ComponentTest::ComponentTestManagerProxy::GetTestConfigPage().c_str());
70         ComponentTest::ComponentTestManagerProxy::Finish();
71         std::exit(0);
72     });
73     return nullptr;
74 }
75 
JSDefineTestGetCaseSize(napi_env env, napi_value arg)76 ComponentTest::TestCaseSize JSDefineTestGetCaseSize(napi_env env, napi_value arg)
77 {
78     napi_value size = nullptr;
79     uint32_t testCaseSize = 0;
80     bool hasSize = false;
81     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_has_named_property(env, arg, "size", &hasSize) == napi_ok,
82         ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseSize::INVALID_SIZE);
83     if (hasSize) {
84         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_named_property(env, arg, "size", &size) == napi_ok,
85             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseSize::INVALID_SIZE);
86         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, size) == napi_number, ErrCode::RET_ERROR_PARAM_INVALID,
87             "Parameter attr.size is not of type number", ComponentTest::TestCaseSize::INVALID_SIZE);
88         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_value_uint32(env, size, &testCaseSize) == napi_ok,
89             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseSize::INVALID_SIZE);
90         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env,
91             testCaseSize >= ComponentTest::TestCaseSize::SMALLTEST &&
92                 testCaseSize < ComponentTest::TestCaseSize::INVALID_SIZE,
93             ErrCode::RET_ERROR_PARAM_INVALID, "Exceeds the range of size", ComponentTest::TestCaseSize::INVALID_SIZE);
94         ComponentTest::TestCaseSize(testCaseSize);
95     }
96     return ComponentTest::TestCaseSize::SMALLTEST;
97 }
98 
JSDefineTestGetCaseType(napi_env env, napi_value arg)99 ComponentTest::TestCaseType JSDefineTestGetCaseType(napi_env env, napi_value arg)
100 {
101     napi_value type = nullptr;
102     uint32_t testCaseType = 0;
103     bool hasType = false;
104     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_has_named_property(env, arg, "type", &hasType) == napi_ok,
105         ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseType::INVALID_TYPE);
106     if (hasType) {
107         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_named_property(env, arg, "type", &type) == napi_ok,
108             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseType::INVALID_TYPE);
109         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, type) == napi_number, ErrCode::RET_ERROR_PARAM_INVALID,
110             "Parameter attr.type is not of type number", ComponentTest::TestCaseType::INVALID_TYPE);
111         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_value_uint32(env, type, &testCaseType) == napi_ok,
112             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseType::INVALID_TYPE);
113         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env,
114             testCaseType >= ComponentTest::TestCaseType::FUNCTION &&
115                 testCaseType < ComponentTest::TestCaseType::INVALID_TYPE,
116             ErrCode::RET_ERROR_PARAM_INVALID, "Exceeds the range of type", ComponentTest::TestCaseType::INVALID_TYPE);
117         ComponentTest::TestCaseType(testCaseType);
118     }
119     return ComponentTest::TestCaseType::FUNCTION;
120 }
121 
JSDefineTestGetCaseLevel(napi_env env, napi_value arg)122 ComponentTest::TestCaseLevel JSDefineTestGetCaseLevel(napi_env env, napi_value arg)
123 {
124     napi_value level = nullptr;
125     uint32_t testCaseLevel = 0;
126     bool hasLevel = false;
127     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_has_named_property(env, arg, "level", &hasLevel) == napi_ok,
128         ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseLevel::INVALID_LEVEL);
129     if (hasLevel) {
130         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_named_property(env, arg, "level", &level) == napi_ok,
131             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseLevel::INVALID_LEVEL);
132         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, level) == napi_number,
133             ErrCode::RET_ERROR_PARAM_INVALID, "Parameter attr.level is not of type number",
134             ComponentTest::TestCaseLevel::INVALID_LEVEL);
135         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, napi_get_value_uint32(env, level, &testCaseLevel) == napi_ok,
136             ErrCode::RET_ERROR_PARAM_INVALID, "Failed to get parameter", ComponentTest::TestCaseLevel::INVALID_LEVEL);
137         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env,
138             testCaseLevel >= ComponentTest::TestCaseLevel::LEVEL0 &&
139                 testCaseLevel < ComponentTest::TestCaseLevel::INVALID_LEVEL,
140             ErrCode::RET_ERROR_PARAM_INVALID, "Exceeds the range of level",
141             ComponentTest::TestCaseLevel::INVALID_LEVEL);
142         return ComponentTest::TestCaseLevel(testCaseLevel);
143     }
144     return ComponentTest::TestCaseLevel::LEVEL0;
145 }
146 
JSDefineTest(napi_env env, napi_callback_info info)147 static napi_value JSDefineTest(napi_env env, napi_callback_info info)
148 {
149     CHECK_COMPONENT_TEST_ENABLED();
150     size_t argc = ARG_COUNT_FOUR;
151     napi_value argv[ARG_COUNT_FOUR] = { nullptr };
152     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
153     COMPONENT_TEST_NAPI_ASSERT(
154         env, argc == ARG_COUNT_THREE || argc == ARG_COUNT_FOUR, ErrCode::RET_ERROR_PARAM_INVALID);
155     std::string testName;
156     std::string errMsg;
157     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, CheckAndParseStr(env, argv[ARG_COUNT_ZERO], testName, errMsg),
158         ErrCode::RET_ERROR_PARAM_INVALID, errMsg, NapiGetUndefined(env));
159     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv[ARG_COUNT_ONE]) == napi_object,
160         ErrCode::RET_ERROR_PARAM_INVALID, "Parameter attr is not of type object", NapiGetUndefined(env));
161     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv[ARG_COUNT_TWO]) == napi_function,
162         ErrCode::RET_ERROR_PARAM_INVALID, "Parameter testBody is not of type function", NapiGetUndefined(env));
163     auto testCaseSize = JSDefineTestGetCaseSize(env, argv[ARG_COUNT_ONE]);
164     CHECK_EQUAL_RETURN(testCaseSize, ComponentTest::TestCaseSize::INVALID_SIZE, NapiGetUndefined(env));
165     auto testCaseType = JSDefineTestGetCaseType(env, argv[ARG_COUNT_ONE]);
166     CHECK_EQUAL_RETURN(testCaseType, ComponentTest::TestCaseType::INVALID_TYPE, NapiGetUndefined(env));
167     auto testCaseLevel = JSDefineTestGetCaseLevel(env, argv[ARG_COUNT_ONE]);
168     CHECK_EQUAL_RETURN(testCaseLevel, ComponentTest::TestCaseLevel::INVALID_LEVEL, NapiGetUndefined(env));
169 
170     ComponentTestAsyncCtx* asyncContext = new (std::nothrow) ComponentTestAsyncCtx();
171     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(
172         env, asyncContext != nullptr, ErrCode::RET_ERR_FAILED, "Failed to create asyncContext.", NapiGetUndefined(env));
173     napi_create_reference(env, argv[ARG_COUNT_TWO], 1, &asyncContext->callbackRef);
174     asyncContext->env = env;
175     if (argc == ARG_COUNT_FOUR) {
176         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv[ARG_COUNT_THREE]) == napi_number,
177             ErrCode::RET_ERROR_PARAM_INVALID, "Parameter delayMs is not of type number", NapiGetUndefined(env));
178         NAPI_CALL(env, napi_get_value_uint32(env, argv[ARG_COUNT_THREE], &asyncContext->delayMs));
179     }
180     ComponentTest::TestCaseAttribute attr(testName, testCaseType, testCaseSize, testCaseLevel);
181 
182     ComponentTest::ComponentTestManagerProxy::PostJSTask(
183         [attr](void* data) {
184             ComponentTest::ComponentTestManagerProxy::SetTestCaseAttribute(attr);
185             ComponentTestAsyncCtx* asyncContext = reinterpret_cast<ComponentTestAsyncCtx*>(data);
186             napi_value callback = nullptr;
187             napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &callback);
188             napi_call_function(asyncContext->env, nullptr, callback, 0, nullptr, &asyncContext->asyncResult);
189         },
190         [](void* data) {
191             ComponentTestAsyncCtx* asyncContext = reinterpret_cast<ComponentTestAsyncCtx*>(data);
192             napi_delete_reference(asyncContext->env, asyncContext->callbackRef);
193             delete asyncContext;
194             asyncContext = nullptr;
195         },
196         (void*)asyncContext, asyncContext->delayMs);
197     return nullptr;
198 }
199 
AssertArrayContain(napi_env env, napi_value array, napi_value object)200 napi_value AssertArrayContain(napi_env env, napi_value array, napi_value object)
201 {
202     bool expectIsArray = false;
203     NAPI_CALL(env, napi_is_array(env, array, &expectIsArray));
204     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, expectIsArray, ErrCode::RET_ERROR_PARAM_INVALID,
205         "Parameter expectValue is not of type string or array", NapiGetUndefined(env));
206     bool result = false;
207     uint32_t expectLength = 0;
208     NAPI_CALL(env, napi_get_array_length(env, array, &expectLength));
209     uint32_t actualArrayIndex = 0;
210     for (uint32_t i = 0; i < expectLength; i++) {
211         napi_handle_scope scope = nullptr;
212         napi_open_handle_scope(env, &scope);
213         napi_value expectElement = nullptr;
214         napi_has_element(env, array, i, &result);
215         if (!result) {
216             napi_close_handle_scope(env, scope);
217             break;
218         }
219         napi_get_element(env, array, i, &expectElement);
220         napi_strict_equals(env, expectElement, object, &result);
221         napi_close_handle_scope(env, scope);
222         if (result) {
223             break;
224         }
225     }
226     std::string expectStr = NapiValueToString(env, array);
227     std::string actualStr = NapiValueToString(env, object);
228     ComponentTestRecord(result, "Expect [" + expectStr + "] to contain '" + actualStr + "'.");
229     if (!result) {
230         LOGE("%{public}s", "Expect expectValue to contain actualValue failed.");
231         COMPONENT_TEST_NAPI_JS_ASSERTION_FAIL(env, ErrCode::RET_ERR_ASSERTION_CONTAINS);
232     }
233     return NapiGetUndefined(env);
234 }
235 
JSAssertContain(napi_env env, napi_callback_info info)236 napi_value JSAssertContain(napi_env env, napi_callback_info info)
237 {
238     CHECK_COMPONENT_TEST_ENABLED();
239     size_t argc = ARG_COUNT_TWO;
240     napi_value argv[ARG_COUNT_TWO] = { nullptr };
241     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
242     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, argc == ARG_COUNT_TWO, ErrCode::RET_ERROR_PARAM_INVALID,
243         "Failed to get parameters", NapiGetUndefined(env));
244     if (GetValueType(env, argv[0]) == napi_string) {
245         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv[ARG_COUNT_ONE]) == napi_string,
246             ErrCode::RET_ERROR_PARAM_INVALID,
247             "Parameter expectValue is a string but parameter actualValue is not a string", NapiGetUndefined(env));
248         std::string expectStr = NapiValueToString(env, argv[0]);
249         std::string actualStr = NapiValueToString(env, argv[1]);
250         bool strResult = expectStr.find(actualStr) != std::string::npos;
251         ComponentTestRecord(strResult, "Expect '" + expectStr + "' to contain '" + actualStr + "'.");
252         if (!strResult) {
253             COMPONENT_TEST_NAPI_JS_ASSERTION_FAIL(env, ErrCode::RET_ERR_ASSERTION_CONTAINS);
254         }
255     } else {
256         AssertArrayContain(env, argv[0], argv[ARG_COUNT_ONE]);
257     }
258     return NapiGetUndefined(env);
259 }
260 
ResourceToNapiString(napi_env env, napi_value resource)261 napi_value ResourceToNapiString(napi_env env, napi_value resource)
262 {
263     CompleteResourceParam(env, resource);
264     ResourceInfo resourceInfo;
265     std::string resourceStr;
266     if (ParseResourceParam(env, resource, resourceInfo)) {
267         if (resourceInfo.type == static_cast<int>(ResourceType::MEDIA)) {
268             auto resourceWrapper = CreateResourceWrapper(resourceInfo);
269             std::string pathStr;
270             if (resourceInfo.resId == -1) {
271                 pathStr = resourceWrapper->GetMediaPathByName(resourceInfo.params[0]);
272             } else {
273                 pathStr = resourceWrapper->GetMediaPath(resourceInfo.resId);
274             }
275             return CreateNapiString(env, pathStr);
276         } else if (ParseString(resourceInfo, resourceStr)) {
277             return CreateNapiString(env, resourceStr);
278         }
279     }
280     return nullptr;
281 }
282 
JSAssertEqual(napi_env env, napi_callback_info info)283 napi_value JSAssertEqual(napi_env env, napi_callback_info info)
284 {
285     CHECK_COMPONENT_TEST_ENABLED();
286     size_t argc = ARG_COUNT_TWO;
287     napi_value argv[ARG_COUNT_TWO] = { nullptr };
288     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
289     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, argc == ARG_COUNT_TWO, ErrCode::RET_ERROR_PARAM_INVALID,
290         "Failed to get parameters", NapiGetUndefined(env));
291     napi_value expectValue = argv[ARG_COUNT_ONE];
292     napi_value actualValue = argv[0];
293     napi_value napiStrExpect = ResourceToNapiString(env, expectValue);
294     if (napiStrExpect) {
295         expectValue = napiStrExpect;
296     }
297     napi_value napiStrActual = ResourceToNapiString(env, actualValue);
298     if (napiStrActual) {
299         actualValue = napiStrActual;
300     }
301 
302     napi_value expectValueNapiString;
303     napi_value actualValueNapiString;
304     char expectStrBuffer[NAPI_MAX_BUF_LEN] = { 0 };
305     char actualStrBuffer[NAPI_MAX_BUF_LEN] = { 0 };
306     NAPI_CALL(env, napi_coerce_to_string(env, expectValue, &expectValueNapiString));
307     NAPI_CALL(env, napi_coerce_to_string(env, actualValue, &actualValueNapiString));
308     size_t expectBufSize = 0;
309     size_t actualBufSize = 0;
310     NAPI_CALL(
311         env, napi_get_value_string_utf8(env, expectValueNapiString, expectStrBuffer, NAPI_MAX_BUF_LEN, &expectBufSize));
312     NAPI_CALL(
313         env, napi_get_value_string_utf8(env, actualValueNapiString, actualStrBuffer, NAPI_MAX_BUF_LEN, &actualBufSize));
314     std::string expectStr(expectStrBuffer, expectBufSize);
315     std::string actualStr(actualStrBuffer, actualBufSize);
316     bool result = false;
317     NAPI_CALL(env, napi_strict_equals(env, expectValue, actualValue, &result));
318 
319     std::string assertionDescription;
320     if (!result) {
321         if (GetValueType(env, expectValue) == napi_object && GetValueType(env, actualValue) == napi_object) {
322             assertionDescription =
323                 "Expect a value equal to '" + expectStr + "', but getting '" + actualStr + "'(different references).";
324         } else {
325             assertionDescription = "Expect a value equal to '" + expectStr + "', but getting '" + actualStr + "'.";
326         }
327         LOGE("%{public}s", assertionDescription.c_str());
328         ComponentTestRecord(result, assertionDescription);
329         COMPONENT_TEST_NAPI_JS_ASSERTION_FAIL(env, ErrCode::RET_ERR_ASSERTION_EQUAL);
330     } else {
331         assertionDescription = "Expect a value equal to '" + expectStr + "'.";
332         ComponentTestRecord(result, assertionDescription);
333     }
334     return NapiGetUndefined(env);
335 }
336 
JSAssertFalse(napi_env env, napi_callback_info info)337 napi_value JSAssertFalse(napi_env env, napi_callback_info info)
338 {
339     CHECK_COMPONENT_TEST_ENABLED();
340     size_t argc = ARG_COUNT_ONE;
341     napi_value argv = nullptr;
342     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr));
343     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID,
344         "Failed to get parameters", NapiGetUndefined(env));
345 
346     bool result = false;
347     std::string assertionDescription;
348     if (GetValueType(env, argv) == napi_boolean) {
349         NAPI_CALL(env, napi_get_value_bool(env, argv, &result));
350         if (result) {
351             assertionDescription = "Expect the value to be 'false', but getting 'true'.";
352         }
353     } else if (GetValueType(env, argv) == napi_string) {
354         size_t bufSize = 0;
355         napi_value napiString;
356         char strBuffer[NAPI_MAX_BUF_LEN] = { 0 };
357         NAPI_CALL(env, napi_coerce_to_string(env, argv, &napiString));
358         NAPI_CALL(env, napi_get_value_string_utf8(env, napiString, strBuffer, NAPI_MAX_BUF_LEN, &bufSize));
359         std::string actualStr(strBuffer, bufSize);
360         std::string lowerActualStr = actualStr;
361         std::transform(actualStr.begin(), actualStr.end(), lowerActualStr.begin(), ::tolower);
362         if (lowerActualStr == std::string("true")) {
363             result = true;
364             assertionDescription = "Expect the value to be 'false', but getting 'true'.";
365         } else if (lowerActualStr != std::string("false")) {
366             result = true;
367             assertionDescription = "Unable to recognize '" + actualStr + "' as a string representing a Boolean value.";
368         }
369     } else {
370         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, false, ErrCode::RET_ERROR_PARAM_INVALID,
371             "The parameter is not a Boolean type or a string", NapiGetUndefined(env));
372     }
373     if (result) {
374         LOGE("%{public}s", assertionDescription.c_str());
375         ComponentTestRecord(!result, assertionDescription);
376         COMPONENT_TEST_NAPI_JS_ASSERTION_FAIL(env, ErrCode::RET_ERR_ASSERTION_FALSE);
377     } else {
378         assertionDescription = "Expect the value to be 'false'.";
379         ComponentTestRecord(!result, assertionDescription);
380     }
381     return NapiGetUndefined(env);
382 }
383 
JSAssertTrue(napi_env env, napi_callback_info info)384 napi_value JSAssertTrue(napi_env env, napi_callback_info info)
385 {
386     CHECK_COMPONENT_TEST_ENABLED();
387     size_t argc = ARG_COUNT_ONE;
388     napi_value argv = nullptr;
389     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr));
390     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID,
391         "Failed to get parameters", NapiGetUndefined(env));
392 
393     bool result = false;
394     std::string assertionDescription;
395     if (GetValueType(env, argv) == napi_boolean) {
396         NAPI_CALL(env, napi_get_value_bool(env, argv, &result));
397         if (!result) {
398             assertionDescription = "Expect the value to be 'true', but getting 'false'.";
399         }
400     } else if (GetValueType(env, argv) == napi_string) {
401         size_t bufSize = 0;
402         napi_value napiString;
403         char strBuffer[NAPI_MAX_BUF_LEN] = { 0 };
404         NAPI_CALL(env, napi_coerce_to_string(env, argv, &napiString));
405         NAPI_CALL(env, napi_get_value_string_utf8(env, napiString, strBuffer, NAPI_MAX_BUF_LEN, &bufSize));
406         std::string actualStr(strBuffer, bufSize);
407         std::string lowerActualStr = actualStr;
408         std::transform(actualStr.begin(), actualStr.end(), lowerActualStr.begin(), ::tolower);
409         if (lowerActualStr == std::string("true")) {
410             result = true;
411         } else if (lowerActualStr == std::string("false")) {
412             assertionDescription = "Expect the value to be 'true', but getting 'false'.";
413         } else {
414             assertionDescription = "Unable to recognize '" + actualStr + "' as a string representing a Boolean value.";
415         }
416     } else {
417         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, false, ErrCode::RET_ERROR_PARAM_INVALID,
418             "The parameter is not a Boolean type or a string", NapiGetUndefined(env));
419     }
420     if (!result) {
421         LOGE("%{public}s", assertionDescription.c_str());
422         ComponentTestRecord(result, assertionDescription);
423         COMPONENT_TEST_NAPI_JS_ASSERTION_FAIL(env, ErrCode::RET_ERR_ASSERTION_TRUE);
424     } else {
425         assertionDescription = "Expect the value to be 'true'.";
426         ComponentTestRecord(result, assertionDescription);
427     }
428     return NapiGetUndefined(env);
429 }
430 
componentTestExport(napi_env env, napi_value exports)431 static napi_value componentTestExport(napi_env env, napi_value exports)
432 {
433     napi_property_descriptor desc[] = {
434         DECLARE_NAPI_FUNCTION("loadComponentTestEntry", JSLoadComponentTestEntry),
435         DECLARE_NAPI_FUNCTION("defineTest", JSDefineTest),
436         DECLARE_NAPI_FUNCTION("assertContain", JSAssertContain),
437         DECLARE_NAPI_FUNCTION("assertEqual", JSAssertEqual),
438         DECLARE_NAPI_FUNCTION("assertFalse", JSAssertFalse),
439         DECLARE_NAPI_FUNCTION("assertTrue", JSAssertTrue),
440     };
441     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
442     NAPI_CALL(env, ComponentTestTester::DefineComponentTestTester(env, exports));
443     NAPI_CALL(env, ComponentTestMatcher::DefineComponentTestMatcher(env, exports));
444     NAPI_CALL(env, ComponentTestComponent::DefineComponentTestComponent(env, exports));
445     NAPI_CALL(env, ExportEnumerator(env, exports, TEST_CASE_TYPE_DEF));
446     NAPI_CALL(env, ExportEnumerator(env, exports, TEST_CASE_SIZE_DEF));
447     NAPI_CALL(env, ExportEnumerator(env, exports, TEST_CASE_LEVEL_DEF));
448     NAPI_CALL(env, ExportEnumerator(env, exports, MATCH_TYPE_DEF));
449     NAPI_CALL(env, ExportEnumerator(env, exports, UI_DIRECTION_DEF));
450 
451     return exports;
452 }
453 
454 static napi_module componentTestModule = {
455     .nm_version = 1,
456     .nm_flags = 0,
457     .nm_filename = nullptr,
458     .nm_register_func = componentTestExport,
459     .nm_modname = "arkui.componentTest",
460     .nm_priv = ((void*)0),
461     .reserved = { 0 },
462 };
463 
ComponentTestRegister()464 extern "C" __attribute__((constructor)) void ComponentTestRegister()
465 {
466     napi_module_register(&componentTestModule);
467 }
468 } // namespace OHOS::Ace::Napi
469