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