• 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(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