• 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 "widget_matcher.h"
17 
18 namespace OHOS::uitest {
19     using namespace std;
20     using namespace nlohmann;
21 
GetRuleName(ValueMatchRule rule)22     string GetRuleName(ValueMatchRule 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,ValueMatchRule rule)58     WidgetAttrMatcher::WidgetAttrMatcher(string_view attr, string_view testValue, ValueMatchRule 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 
WriteIntoParcel(json & data) const77     void WidgetAttrMatcher::WriteIntoParcel(json &data) const
78     {
79         data["attr_name"] = attrName_;
80         data["test_value"] = testVal_;
81         data["match_rule"] = matchRule_;
82     }
83 
ReadFromParcel(const json & data)84     void WidgetAttrMatcher::ReadFromParcel(const json &data)
85     {
86         attrName_ = data["attr_name"];
87         testVal_ = data["test_value"];
88         uint8_t intVal = data["match_rule"];
89         matchRule_ = static_cast<ValueMatchRule>(intVal);
90     }
91 
All(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)92     All::All(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb)
93     {
94         matchers_.emplace_back(ma);
95         matchers_.emplace_back(mb);
96     }
97 
All(const vector<WidgetAttrMatcher> & matchers)98     All::All(const vector<WidgetAttrMatcher> &matchers)
99     {
100         for (auto &ref:matchers) {
101             this->matchers_.emplace_back(ref);
102         }
103     }
104 
Matches(const Widget & testedValue) const105     bool All::Matches(const Widget &testedValue) const
106     {
107         bool match = true;
108         for (auto &matcher:matchers_) {
109             match = match && matcher.Matches(testedValue);
110             if (!match) {
111                 break;
112             }
113         }
114         return match;
115     }
116 
Describe() const117     string All::Describe() const
118     {
119         stringstream desc;
120         uint32_t index = 0;
121         for (auto &matcher:matchers_) {
122             if (index > 0) {
123                 desc << " AND ";
124             }
125             desc << "(" << matcher.Describe() << ")";
126             index++;
127         }
128         return desc.str();
129     }
130 
Matches(const Widget & widget) const131     bool RootMatcher::Matches(const Widget &widget) const
132     {
133         return WidgetTree::IsRootWidgetHierarchy(widget.GetHierarchy());
134     }
135 
Describe() const136     string RootMatcher::Describe() const
137     {
138         return "the root widget on the tree";
139     }
140 
Visit(const Widget & widget)141     void MatchedWidgetCollector::Visit(const Widget &widget)
142     {
143         if (matcher_.Matches(widget)) {
144             receiver_.emplace_back(widget);
145         }
146     }
147 
Any(const WidgetAttrMatcher & ma,const WidgetAttrMatcher & mb)148     Any::Any(const WidgetAttrMatcher &ma, const WidgetAttrMatcher &mb)
149     {
150         matchers_.emplace_back(ma);
151         matchers_.emplace_back(mb);
152     }
153 
Any(const vector<WidgetAttrMatcher> & matchers)154     Any::Any(const vector<WidgetAttrMatcher> &matchers)
155     {
156         for (auto &ref:matchers) {
157             this->matchers_.emplace_back(ref);
158         }
159     }
160 
Matches(const Widget & testedValue) const161     bool Any::Matches(const Widget &testedValue) const
162     {
163         bool match = false;
164         for (auto &matcher:matchers_) {
165             match = match || matcher.Matches(testedValue);
166             if (match) break;
167         }
168         return match;
169     }
170 
Describe() const171     string Any::Describe() const
172     {
173         stringstream desc;
174         uint32_t index = 0;
175         for (auto &matcher:matchers_) {
176             if (index > 0) {
177                 desc << " OR ";
178             }
179             desc << "(" << matcher.Describe() << ")";
180             index++;
181         }
182         return desc.str();
183     }
184 } // namespace uitest