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