• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <algorithm>
17 #include "ui_model.h"
18 #include <regex.h>
19 #include <iostream>
20 
21 namespace OHOS::uitest {
22     using namespace std;
23     using namespace nlohmann;
24 
SetBounds(const Rect & bounds)25     void Widget::SetBounds(const Rect &bounds)
26     {
27         bounds_ = bounds;
28         bounds_.displayId_ = displayId_;
29     }
30 
ToStr() const31     string Widget::ToStr() const
32     {
33         stringstream os;
34         os << "Widget{";
35         for (int i = 0; i < UiAttr::MAX; i++) {
36             os << ATTR_NAMES[i] << "='" << attributeVec_[i] << "',";
37         }
38         os << "}";
39         return os.str();
40     }
41 
Clone(string_view hierarchy) const42     unique_ptr<Widget> Widget::Clone(string_view hierarchy) const
43     {
44         auto clone = make_unique<Widget>(hierarchy);
45         clone->bounds_ = this->bounds_;
46         clone->displayId_ = this->displayId_;
47         clone->attributeVec_ = attributeVec_;
48         return clone;
49     }
50 
GetAttrVec() const51     std::vector<std::string> Widget::GetAttrVec() const
52     {
53         std::vector<std::string> retVec = attributeVec_;
54         if (attributeVec_[UiAttr::BOUNDS].empty()) {
55             stringstream boundStream;
56             boundStream << "[" << bounds_.left_ << "," << bounds_.top_ << "][" << bounds_.right_ << ","
57                         << bounds_.bottom_ << "]";
58             retVec[UiAttr::BOUNDS] = boundStream.str();
59         }
60         return retVec;
61     }
62 
SetAttr(UiAttr attrId,string value)63     void Widget::SetAttr(UiAttr attrId, string value)
64     {
65         if (attrId >= UiAttr::MAX) {
66             LOG_E("Error attrId %{public}d, check it", attrId);
67             return;
68         }
69         attributeVec_[attrId] = value;
70     }
71 
GetAttr(UiAttr attrId) const72     std::string Widget::GetAttr(UiAttr attrId) const
73     {
74         if (attrId >= UiAttr::MAX) {
75             return "none";
76         }
77         if (attrId == UiAttr::BOUNDS && attributeVec_[UiAttr::BOUNDS].empty()) {
78             stringstream boundStream;
79             boundStream << "[" << bounds_.left_ << "," << bounds_.top_ << "][" << bounds_.right_ << ","
80                         << bounds_.bottom_ << "]";
81             return boundStream.str();
82         }
83         return attributeVec_[attrId];
84     }
RegexMatchAttr(std::string_view value,std::string_view attrValue,int flags)85     bool RegexMatchAttr(std::string_view value, std::string_view attrValue, int flags)
86     {
87         regex_t preg;
88         char *patternValue = const_cast<char*>(value.data());
89         char *patternReg = const_cast<char*>(attrValue.data());
90         if ((regcomp(&preg, patternValue, flags)) != 0) {
91             return false;
92         }
93         if (regexec(&preg, patternReg, 0, nullptr, 0) != 0) {
94             return false;
95         }
96         return true;
97     }
98 
MatchAttr(const WidgetMatchModel & matchModel) const99     bool Widget::MatchAttr(const WidgetMatchModel& matchModel) const
100     {
101         UiAttr attr = matchModel.attrName;
102         std::string_view value = matchModel.attrValue;
103         ValueMatchPattern pattern = matchModel.pattern;
104         std::string_view attrValue = attributeVec_[attr];
105         switch (pattern) {
106             case ValueMatchPattern::EQ:
107                 return attrValue == value;
108             case ValueMatchPattern::CONTAINS:
109                 return attrValue.find(value) != std::string_view::npos;
110             case ValueMatchPattern::STARTS_WITH:
111                 return attrValue.find(value) == 0;
112             case ValueMatchPattern::ENDS_WITH:
113                 if (attrValue.length() < value.length()) {
114                     return false;
115                 }
116                 return attrValue.substr(attrValue.length() - value.length()) == value;
117             case ValueMatchPattern::REG_EXP:
118                 {
119                     auto flags = REG_EXTENDED;
120                     return RegexMatchAttr(value, attrValue, flags);
121                 }
122             case ValueMatchPattern::REG_EXP_ICASE:
123                 {
124                     auto flags = REG_EXTENDED | REG_ICASE;
125                     return RegexMatchAttr(value, attrValue, flags);
126                 }
127             default:
128                 break;
129         }
130         return false;
131     }
132 
SetHierarchy(const std::string & hierarch)133     void Widget::SetHierarchy(const std::string &hierarch)
134     {
135         hierarchy_ = hierarch;
136         attributeVec_[UiAttr::HIERARCHY] = hierarch;
137     }
138 
WrapperWidgetToJson(nlohmann::json & out)139     void Widget::WrapperWidgetToJson(nlohmann::json &out)
140     {
141         for (int i = 0; i < UiAttr::HIERARCHY + 1; ++i) {
142             if (i == UiAttr::BOUNDS && attributeVec_[UiAttr::BOUNDS].empty()) {
143                 stringstream boundStream;
144                 boundStream << "[" << bounds_.left_ << "," << bounds_.top_ << "][" << bounds_.right_ << ","
145                             << bounds_.bottom_ << "]";
146                 attributeVec_[i] = boundStream.str();
147             }
148             out[ATTR_NAMES[i].data()] = attributeVec_[i];
149         }
150         out[ATTR_NAMES[UiAttr::VISIBLE].data()] = attributeVec_[UiAttr::VISIBLE];
151         out[ATTR_NAMES[UiAttr::HASHCODE].data()] = attributeVec_[UiAttr::HASHCODE];
152         out[ATTR_NAMES[UiAttr::HINT].data()] = attributeVec_[UiAttr::HINT];
153     }
154 
Build(string_view parentWidgetHierarchy,uint32_t childIndex)155     string WidgetHierarchyBuilder::Build(string_view parentWidgetHierarchy, uint32_t childIndex)
156     {
157         return string(parentWidgetHierarchy) + string(HIERARCHY_SEPARATOR) + to_string(childIndex);
158     }
159 
GetParentWidgetHierarchy(string_view hierarchy)160     string WidgetHierarchyBuilder::GetParentWidgetHierarchy(string_view hierarchy)
161     {
162         if (hierarchy == ROOT_HIERARCHY) {
163             // no parent for root widget
164             return "";
165         }
166 
167         if (hierarchy.find(HIERARCHY_SEPARATOR) == std::string::npos) {
168             return "";
169         }
170 
171         auto findRoot = hierarchy.find(ROOT_HIERARCHY);
172         if (findRoot != 0) {
173             // invalid hierarchy string
174             return "";
175         }
176         auto findLastSeparator = hierarchy.find_last_of(HIERARCHY_SEPARATOR);
177         if (findLastSeparator <= 0 || findLastSeparator == string::npos) {
178             return "";
179         }
180         return string(hierarchy).substr(0, findLastSeparator);
181     }
182 
GetChildHierarchy(string_view hierarchy,uint32_t childIndex)183     string WidgetHierarchyBuilder::GetChildHierarchy(string_view hierarchy, uint32_t childIndex)
184     {
185         if (hierarchy.find(ROOT_HIERARCHY) != 0) {
186             // invalid hierarchy string
187             return "";
188         }
189         return string(hierarchy) + string(HIERARCHY_SEPARATOR) + to_string(childIndex);
190     }
191 } // namespace OHOS::uitest
192