• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Google LLC
2 //
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 #ifndef ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_TEST_UTILS_H_
16 #define ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_TEST_UTILS_H_
17 
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "icing/query/advanced_query_parser/abstract-syntax-tree.h"
25 
26 namespace icing {
27 namespace lib {
28 
29 // A visitor that simply collects the nodes and flattens them in left-side
30 // depth-first order.
31 enum class NodeType {
32   kFunctionName,
33   kString,
34   kText,
35   kMember,
36   kFunction,
37   kUnaryOperator,
38   kNaryOperator
39 };
40 
41 struct NodeInfo {
42   std::string value;
43   NodeType type;
44 
45   bool operator==(const NodeInfo& rhs) const {
46     return value == rhs.value && type == rhs.type;
47   }
48 };
49 
50 MATCHER_P2(EqualsNodeInfo, value, type, "") {
51   if (arg.value != value || arg.type != type) {
52     *result_listener << "(Expected: value=\"" << value
53                      << "\", type=" << static_cast<int>(type)
54                      << ". Actual: value=\"" << arg.value
55                      << "\", type=" << static_cast<int>(arg.type) << ")";
56     return false;
57   }
58   return true;
59 }
60 
61 class SimpleVisitor : public AbstractSyntaxTreeVisitor {
62  public:
VisitFunctionName(const FunctionNameNode * node)63   void VisitFunctionName(const FunctionNameNode* node) override {
64     nodes_.push_back({node->value(), NodeType::kFunctionName});
65   }
VisitString(const StringNode * node)66   void VisitString(const StringNode* node) override {
67     nodes_.push_back({node->value(), NodeType::kString});
68   }
VisitText(const TextNode * node)69   void VisitText(const TextNode* node) override {
70     nodes_.push_back({node->value(), NodeType::kText});
71   }
VisitMember(const MemberNode * node)72   void VisitMember(const MemberNode* node) override {
73     for (const std::unique_ptr<TextNode>& child : node->children()) {
74       child->Accept(this);
75     }
76     if (node->function() != nullptr) {
77       node->function()->Accept(this);
78     }
79     nodes_.push_back({"", NodeType::kMember});
80   }
VisitFunction(const FunctionNode * node)81   void VisitFunction(const FunctionNode* node) override {
82     node->function_name()->Accept(this);
83     for (const std::unique_ptr<Node>& arg : node->args()) {
84       arg->Accept(this);
85     }
86     nodes_.push_back({"", NodeType::kFunction});
87   }
VisitUnaryOperator(const UnaryOperatorNode * node)88   void VisitUnaryOperator(const UnaryOperatorNode* node) override {
89     node->child()->Accept(this);
90     nodes_.push_back({node->operator_text(), NodeType::kUnaryOperator});
91   }
VisitNaryOperator(const NaryOperatorNode * node)92   void VisitNaryOperator(const NaryOperatorNode* node) override {
93     for (const std::unique_ptr<Node>& child : node->children()) {
94       child->Accept(this);
95     }
96     nodes_.push_back({node->operator_text(), NodeType::kNaryOperator});
97   }
98 
nodes()99   const std::vector<NodeInfo>& nodes() const { return nodes_; }
100 
101  private:
102   std::vector<NodeInfo> nodes_;
103 };
104 
105 }  // namespace lib
106 }  // namespace icing
107 
108 #endif  // ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_TEST_UTILS_H_
109