• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "js_component_test_matcher.h"
17 
18 #include <string>
19 
20 #include "component_test/component_test_proxy.h"
21 #include "interfaces/napi/kits/utils/napi_utils.h"
22 #include "js_component_test_utils.h"
23 #include "napi/native_api.h"
24 #include "napi/native_node_api.h"
25 
26 #include "base/log/log.h"
27 #include "base/utils/utils.h"
28 
29 namespace OHOS::Ace::Napi {
30 namespace {
31 constexpr char CREATE[] = "create";
32 constexpr char TEXT[] = "text";
33 constexpr char ID[] = "id";
34 constexpr char TYPE[] = "type";
35 constexpr char CLICKABLE[] = "clickable";
36 constexpr char LONGPRESSABLE[] = "longPressable";
37 constexpr char SCROLLABLE[] = "scrollable";
38 constexpr char ENABLED[] = "enabled";
39 constexpr char FOCUSED[] = "focused";
40 constexpr char SELECTED[] = "selected";
41 constexpr char CHECKED[] = "checked";
42 constexpr char CHECKABLE[] = "checkable";
43 } // namespace
44 
45 thread_local napi_ref ComponentTestMatcher::constructorRef_ = nullptr;
46 
DefineComponentTestMatcher(napi_env env,napi_value exports)47 napi_status ComponentTestMatcher::DefineComponentTestMatcher(napi_env env, napi_value exports)
48 {
49     napi_value constructor = nullptr;
50 
51     napi_property_descriptor desc[] = {
52         DECLARE_NAPI_STATIC_FUNCTION(CREATE, JSCreate),
53         DECLARE_NAPI_FUNCTION(TEXT, JSText),
54         DECLARE_NAPI_FUNCTION(ID, JSId),
55         DECLARE_NAPI_FUNCTION(TYPE, JSType),
56         DECLARE_NAPI_FUNCTION_WITH_DATA(CLICKABLE, GenericBoolCallback, (void*)CLICKABLE),
57         DECLARE_NAPI_FUNCTION_WITH_DATA(LONGPRESSABLE, GenericBoolCallback, (void*)LONGPRESSABLE),
58         DECLARE_NAPI_FUNCTION_WITH_DATA(SCROLLABLE, GenericBoolCallback, (void*)SCROLLABLE),
59         DECLARE_NAPI_FUNCTION_WITH_DATA(ENABLED, GenericBoolCallback, (void*)ENABLED),
60         DECLARE_NAPI_FUNCTION_WITH_DATA(FOCUSED, GenericBoolCallback, (void*)FOCUSED),
61         DECLARE_NAPI_FUNCTION_WITH_DATA(SELECTED, GenericBoolCallback, (void*)SELECTED),
62         DECLARE_NAPI_FUNCTION_WITH_DATA(CHECKED, GenericBoolCallback, (void*)CHECKED),
63         DECLARE_NAPI_FUNCTION_WITH_DATA(CHECKABLE, GenericBoolCallback, (void*)CHECKABLE),
64     };
65 
66     NAPI_CALL_BASE(env,
67         napi_define_class(env, MATCHER_NAME, NAPI_AUTO_LENGTH, Constructor, nullptr,
68             sizeof(desc) / sizeof(napi_property_descriptor), desc, &constructor),
69         NAPI_ERR);
70     NAPI_CALL_BASE(env, napi_set_named_property(env, exports, MATCHER_NAME, constructor), NAPI_ERR);
71     NAPI_CALL_BASE(env, napi_create_reference(env, constructor, 1, &constructorRef_), NAPI_ERR);
72 
73     return napi_ok;
74 }
75 
Constructor(napi_env env,napi_callback_info info)76 napi_value ComponentTestMatcher::Constructor(napi_env env, napi_callback_info info)
77 {
78     napi_value thisVar = nullptr;
79     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
80     ComponentTest::ComponentTestMatcherImpl* matcherImpl = new (std::nothrow) ComponentTest::ComponentTestMatcherImpl();
81     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(
82         env, matcherImpl != nullptr, ErrCode::RET_ERR_FAILED, "Failed to create matcherImpl.", NapiGetUndefined(env));
83     NAPI_CALL_BASE(env, napi_wrap(env, thisVar, matcherImpl, Destructor, nullptr, nullptr), thisVar);
84     return thisVar;
85 }
86 
Destructor(napi_env env,void * data,void * hint)87 void ComponentTestMatcher::Destructor(napi_env env, void* data, void* hint)
88 {
89     ComponentTest::ComponentTestMatcherImpl* matcherImpl =
90         reinterpret_cast<ComponentTest::ComponentTestMatcherImpl*>(data);
91     CHECK_NULL_VOID(matcherImpl);
92     if (constructorRef_ != nullptr) {
93         napi_delete_reference(env, constructorRef_);
94     }
95     delete matcherImpl;
96     matcherImpl = nullptr;
97 }
98 
JSCreate(napi_env env,napi_callback_info info)99 napi_value ComponentTestMatcher::JSCreate(napi_env env, napi_callback_info info)
100 {
101     CHECK_COMPONENT_TEST_ENABLED();
102     napi_value constructor = nullptr;
103     napi_value thisVar = nullptr;
104     NAPI_CALL(env, napi_get_reference_value(env, constructorRef_, &constructor));
105     NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &thisVar));
106     COMPONENT_TEST_NAPI_ASSERT(env, thisVar != nullptr, ErrCode::RET_ERR_FAILED);
107     return thisVar;
108 }
109 
JSText(napi_env env,napi_callback_info info)110 napi_value ComponentTestMatcher::JSText(napi_env env, napi_callback_info info)
111 {
112     size_t argc = ARG_COUNT_TWO;
113     napi_value argv[ARG_COUNT_TWO] = { nullptr };
114     napi_value thisVar = nullptr;
115     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
116     COMPONENT_TEST_NAPI_ASSERT(env, argc == ARG_COUNT_ONE || argc == ARG_COUNT_TWO, ErrCode::RET_ERROR_PARAM_INVALID);
117 
118     std::string text;
119     std::string errMsg;
120     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, CheckAndParseStr(env, argv[ARG_COUNT_ZERO], text, errMsg),
121         ErrCode::RET_ERROR_PARAM_INVALID, errMsg, NapiGetUndefined(env));
122     ComponentTest::ComponentTestMatcherImpl* matcherImpl = GetMatcher(env, thisVar);
123     CHECK_NULL_RETURN(matcherImpl, NapiGetUndefined(env));
124     if (argc == ARG_COUNT_TWO) {
125         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, GetValueType(env, argv[ARG_COUNT_ONE]) == napi_number,
126             ErrCode::RET_ERROR_PARAM_INVALID, "Parameter is not of type number", NapiGetUndefined(env));
127         int32_t matchType = 0;
128         NAPI_CALL(env, napi_get_value_int32(env, argv[ARG_COUNT_ONE], &matchType));
129         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(
130             env, matchType >= 0, ErrCode::RET_ERROR_PARAM_INVALID, "Exceeds the range of types", NapiGetUndefined(env));
131         ComponentTest::MatchType enumValue = static_cast<ComponentTest::MatchType>(matchType);
132         matcherImpl->SetText(text, enumValue);
133     } else {
134         matcherImpl->SetText(text);
135     }
136     return thisVar;
137 }
138 
JSId(napi_env env,napi_callback_info info)139 napi_value ComponentTestMatcher::JSId(napi_env env, napi_callback_info info)
140 {
141     size_t argc = ARG_COUNT_ONE;
142     napi_value argv = nullptr;
143     napi_value thisVar = nullptr;
144     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, nullptr));
145     COMPONENT_TEST_NAPI_ASSERT(env, argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID);
146 
147     std::string id;
148     std::string errMsg;
149     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(
150         env, CheckAndParseStr(env, argv, id, errMsg), ErrCode::RET_ERROR_PARAM_INVALID, errMsg, NapiGetUndefined(env));
151     ComponentTest::ComponentTestMatcherImpl* matcherImpl = GetMatcher(env, thisVar);
152     CHECK_NULL_RETURN(matcherImpl, NapiGetUndefined(env));
153     matcherImpl->SetId(id);
154     return thisVar;
155 }
156 
JSType(napi_env env,napi_callback_info info)157 napi_value ComponentTestMatcher::JSType(napi_env env, napi_callback_info info)
158 {
159     size_t argc = ARG_COUNT_ONE;
160     napi_value argv = nullptr;
161     napi_value thisVar = nullptr;
162     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, nullptr));
163     COMPONENT_TEST_NAPI_ASSERT(env, argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID);
164 
165     std::string type;
166     std::string errMsg;
167     COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, CheckAndParseStr(env, argv, type, errMsg), ErrCode::RET_ERROR_PARAM_INVALID,
168         errMsg, NapiGetUndefined(env));
169     ComponentTest::ComponentTestMatcherImpl* matcherImpl = GetMatcher(env, thisVar);
170     CHECK_NULL_RETURN(matcherImpl, NapiGetUndefined(env));
171     matcherImpl->SetType(type);
172     return thisVar;
173 }
174 
GenericBoolCallback(napi_env env,napi_callback_info info)175 napi_value ComponentTestMatcher::GenericBoolCallback(napi_env env, napi_callback_info info)
176 {
177     size_t argc = ARG_COUNT_ONE;
178     void* data = nullptr;
179     napi_value argv = nullptr;
180     napi_value thisVar = nullptr;
181     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
182     COMPONENT_TEST_NAPI_ASSERT(env, argc == ARG_COUNT_ZERO || argc == ARG_COUNT_ONE, ErrCode::RET_ERROR_PARAM_INVALID);
183     COMPONENT_TEST_NAPI_ASSERT(env, data != nullptr, ErrCode::RET_ERR_FAILED);
184     bool res = true;
185     std::string errMsg;
186     if (argc == ARG_COUNT_ONE) {
187         COMPONENT_TEST_NAPI_ASSERT_CUSTOM(env, CheckAndParseBool(env, argv, res, errMsg),
188             ErrCode::RET_ERROR_PARAM_INVALID, errMsg, NapiGetUndefined(env));
189     }
190     ComponentTest::ComponentTestMatcherImpl* matcherImpl = GetMatcher(env, thisVar);
191     CHECK_NULL_RETURN(matcherImpl, NapiGetUndefined(env));
192 
193     const char* functionName = static_cast<const char*>(data);
194     if (std::strcmp(functionName, "clickable") == 0) {
195         matcherImpl->SetClickable(res);
196     } else if (std::strcmp(functionName, "longPressable") == 0) {
197         matcherImpl->SetLongPressable(res);
198     } else if (std::strcmp(functionName, "scrollable") == 0) {
199         matcherImpl->SetScrollable(res);
200     } else if (std::strcmp(functionName, "enabled") == 0) {
201         matcherImpl->SetEnabled(res);
202     } else if (std::strcmp(functionName, "focused") == 0) {
203         matcherImpl->SetFocused(res);
204     } else if (std::strcmp(functionName, "selected") == 0) {
205         matcherImpl->SetSelected(res);
206     } else if (std::strcmp(functionName, "checked") == 0) {
207         matcherImpl->SetChecked(res);
208     } else if (std::strcmp(functionName, "checkable") == 0) {
209         matcherImpl->SetCheckable(res);
210     } else {
211         LOGW("Unknown function %{public}s", functionName);
212     }
213     return thisVar;
214 }
215 
216 } // namespace OHOS::Ace::Napi
217