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_) == (testedValue.length() - testValue_.length())); 47 } 48 } 49 Describe() const50 string ValueMatcher::Describe() const 51 { 52 stringstream ss; 53 ss << GetRuleName(rule_); 54 ss << " '" << testValue_ << "'"; 55 return ss.str(); 56 } 57 WidgetAttrMatcher(string_view attr,string_view testValue,ValueMatchPattern rule)58 WidgetAttrMatcher::WidgetAttrMatcher(string_view attr, string_view testValue, ValueMatchPattern rule) 59 : attrName_(attr), testVal_(testValue), matchRule_(rule) {} 60 Matches(const Widget & widget) const61 bool WidgetAttrMatcher::Matches(const Widget &widget) const 62 { 63 if (!widget.HasAttr(attrName_)) { 64 return false; 65 } 66 auto attrValue = widget.GetAttr(attrName_, ""); 67 auto valueMatcher = ValueMatcher(testVal_, matchRule_); 68 return valueMatcher.Matches(attrValue); 69 }; 70 Describe() const71 string WidgetAttrMatcher::Describe() const 72 { 73 auto valueMatcher = ValueMatcher(testVal_, matchRule_); 74 return "$" + string(attrName_) + " " + valueMatcher.Describe(); 75 } 76 All(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)77 All::All(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb) 78 { 79 matchers_.emplace_back(ma); 80 matchers_.emplace_back(mb); 81 } 82 All(const vector<WidgetAttrMatcher> & matchers)83 All::All(const vector<WidgetAttrMatcher> &matchers) 84 { 85 for (auto &ref:matchers) { 86 this->matchers_.emplace_back(ref); 87 } 88 } 89 Matches(const Widget & testedValue) const90 bool All::Matches(const Widget &testedValue) const 91 { 92 bool match = true; 93 for (auto &matcher:matchers_) { 94 match = match && matcher.Matches(testedValue); 95 if (!match) { 96 break; 97 } 98 } 99 return match; 100 } 101 Describe() const102 string All::Describe() const 103 { 104 stringstream desc; 105 uint32_t index = 0; 106 for (auto &matcher:matchers_) { 107 if (index > 0) { 108 desc << " AND "; 109 } 110 desc << "(" << matcher.Describe() << ")"; 111 index++; 112 } 113 return desc.str(); 114 } 115 Matches(const Widget & widget) const116 bool RootMatcher::Matches(const Widget &widget) const 117 { 118 return WidgetTree::IsRootWidgetHierarchy(widget.GetHierarchy()); 119 } 120 Describe() const121 string RootMatcher::Describe() const 122 { 123 return "the root widget on the tree"; 124 } 125 Visit(const Widget & widget)126 void MatchedWidgetCollector::Visit(const Widget &widget) 127 { 128 if (matcher_.Matches(widget)) { 129 receiver_.emplace_back(widget); 130 } 131 } 132 Any(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)133 Any::Any(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb) 134 { 135 matchers_.emplace_back(ma); 136 matchers_.emplace_back(mb); 137 } 138 Any(const vector<WidgetAttrMatcher> & matchers)139 Any::Any(const vector<WidgetAttrMatcher> &matchers) 140 { 141 for (auto &ref:matchers) { 142 this->matchers_.emplace_back(ref); 143 } 144 } 145 Matches(const Widget & testedValue) const146 bool Any::Matches(const Widget &testedValue) const 147 { 148 bool match = false; 149 for (auto &matcher:matchers_) { 150 match = match || matcher.Matches(testedValue); 151 if (match) break; 152 } 153 return match; 154 } 155 Describe() const156 string Any::Describe() const 157 { 158 stringstream desc; 159 uint32_t index = 0; 160 for (auto &matcher:matchers_) { 161 if (index > 0) { 162 desc << " OR "; 163 } 164 desc << "(" << matcher.Describe() << ")"; 165 index++; 166 } 167 return desc.str(); 168 } 169 } // namespace uitest