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