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 "widget_matcher.h" 17 18 namespace OHOS::uitest { 19 using namespace std; 20 using namespace nlohmann; 21 GetRuleName(ValueMatchPattern rule)22 string GetRuleName(ValueMatchPattern rule) 23 { 24 switch (rule) { 25 case EQ: 26 return "="; 27 case CONTAINS: 28 return "contains"; 29 case STARTS_WITH: 30 return "startsWith"; 31 case ENDS_WITH: 32 return "endsWith"; 33 } 34 } 35 Matches(string_view testedValue) const36 bool ValueMatcher::Matches(string_view testedValue) const 37 { 38 switch (rule_) { 39 case EQ: 40 return testedValue == testValue_; 41 case CONTAINS: 42 return testedValue.find(testValue_) != string::npos; 43 case STARTS_WITH: 44 return testedValue.find(testValue_) == 0; 45 case ENDS_WITH: 46 return (testedValue.find(testValue_) != string::npos && 47 testedValue.find(testValue_) == (testedValue.length() - testValue_.length())); 48 } 49 } 50 Describe() const51 string ValueMatcher::Describe() const 52 { 53 stringstream ss; 54 ss << GetRuleName(rule_); 55 ss << " '" << testValue_ << "'"; 56 return ss.str(); 57 } 58 WidgetAttrMatcher(string_view attr,string_view testValue,ValueMatchPattern rule)59 WidgetAttrMatcher::WidgetAttrMatcher(string_view attr, string_view testValue, ValueMatchPattern rule) 60 : attrName_(attr), testVal_(testValue), matchRule_(rule) {} 61 Matches(const Widget & widget) const62 bool WidgetAttrMatcher::Matches(const Widget &widget) const 63 { 64 if (!widget.HasAttr(attrName_)) { 65 return false; 66 } 67 auto attrValue = widget.GetAttr(attrName_, ""); 68 auto valueMatcher = ValueMatcher(testVal_, matchRule_); 69 return valueMatcher.Matches(attrValue); 70 }; 71 Describe() const72 string WidgetAttrMatcher::Describe() const 73 { 74 auto valueMatcher = ValueMatcher(testVal_, matchRule_); 75 return "$" + string(attrName_) + " " + valueMatcher.Describe(); 76 } 77 All(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)78 All::All(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb) 79 { 80 matchers_.emplace_back(ma); 81 matchers_.emplace_back(mb); 82 } 83 All(const vector<WidgetAttrMatcher> & matchers)84 All::All(const vector<WidgetAttrMatcher> &matchers) 85 { 86 for (auto &ref:matchers) { 87 this->matchers_.emplace_back(ref); 88 } 89 } 90 Matches(const Widget & testedValue) const91 bool All::Matches(const Widget &testedValue) const 92 { 93 bool match = true; 94 for (auto &matcher:matchers_) { 95 match = match && matcher.Matches(testedValue); 96 if (!match) { 97 break; 98 } 99 } 100 return match; 101 } 102 Describe() const103 string All::Describe() const 104 { 105 stringstream desc; 106 uint32_t index = 0; 107 for (auto &matcher:matchers_) { 108 if (index > 0) { 109 desc << " AND "; 110 } 111 desc << "(" << matcher.Describe() << ")"; 112 index++; 113 } 114 return desc.str(); 115 } 116 Matches(const Widget & widget) const117 bool RootMatcher::Matches(const Widget &widget) const 118 { 119 return WidgetTree::IsRootWidgetHierarchy(widget.GetHierarchy()); 120 } 121 Describe() const122 string RootMatcher::Describe() const 123 { 124 return "the root widget on the tree"; 125 } 126 Visit(const Widget & widget)127 void MatchedWidgetCollector::Visit(const Widget &widget) 128 { 129 if (matcher_.Matches(widget)) { 130 receiver_.emplace_back(widget); 131 } 132 } 133 Any(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)134 Any::Any(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb) 135 { 136 matchers_.emplace_back(ma); 137 matchers_.emplace_back(mb); 138 } 139 Any(const vector<WidgetAttrMatcher> & matchers)140 Any::Any(const vector<WidgetAttrMatcher> &matchers) 141 { 142 for (auto &ref:matchers) { 143 this->matchers_.emplace_back(ref); 144 } 145 } 146 Matches(const Widget & testedValue) const147 bool Any::Matches(const Widget &testedValue) const 148 { 149 bool match = false; 150 for (auto &matcher:matchers_) { 151 match = match || matcher.Matches(testedValue); 152 if (match) break; 153 } 154 return match; 155 } 156 Describe() const157 string Any::Describe() const 158 { 159 stringstream desc; 160 uint32_t index = 0; 161 for (auto &matcher:matchers_) { 162 if (index > 0) { 163 desc << " OR "; 164 } 165 desc << "(" << matcher.Describe() << ")"; 166 index++; 167 } 168 return desc.str(); 169 } 170 } // namespace uitest