• 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 #include "icing/query/advanced_query_parser/abstract-syntax-tree.h"
16 
17 #include <memory>
18 
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include "icing/query/advanced_query_parser/abstract-syntax-tree-test-utils.h"
22 
23 namespace icing {
24 namespace lib {
25 namespace {
26 
27 using ::testing::ElementsAre;
28 
TEST(AbstractSyntaxTreeTest,Simple)29 TEST(AbstractSyntaxTreeTest, Simple) {
30   std::string_view query = "foo";
31   std::unique_ptr<Node> root = std::make_unique<TextNode>("foo", query);
32   SimpleVisitor visitor;
33   root->Accept(&visitor);
34 
35   EXPECT_THAT(visitor.nodes(),
36               ElementsAre(EqualsNodeInfo("foo", NodeType::kText)));
37 }
38 
TEST(AbstractSyntaxTreeTest,Composite)39 TEST(AbstractSyntaxTreeTest, Composite) {
40   std::string_view query = "(foo bar) OR baz";
41   std::vector<std::unique_ptr<Node>> and_args;
42   and_args.push_back(std::make_unique<TextNode>("foo", query.substr(1, 3)));
43   and_args.push_back(std::make_unique<TextNode>("bar", query.substr(5, 3)));
44   auto and_node =
45       std::make_unique<NaryOperatorNode>("AND", std::move(and_args));
46 
47   std::vector<std::unique_ptr<Node>> or_args;
48   or_args.push_back(std::move(and_node));
49   or_args.push_back(std::make_unique<TextNode>("baz", query.substr(13, 3)));
50   std::unique_ptr<Node> root =
51       std::make_unique<NaryOperatorNode>("OR", std::move(or_args));
52 
53   SimpleVisitor visitor;
54   root->Accept(&visitor);
55 
56   EXPECT_THAT(visitor.nodes(),
57               ElementsAre(EqualsNodeInfo("foo", NodeType::kText),
58                           EqualsNodeInfo("bar", NodeType::kText),
59                           EqualsNodeInfo("AND", NodeType::kNaryOperator),
60                           EqualsNodeInfo("baz", NodeType::kText),
61                           EqualsNodeInfo("OR", NodeType::kNaryOperator)));
62 }
63 
TEST(AbstractSyntaxTreeTest,Function)64 TEST(AbstractSyntaxTreeTest, Function) {
65   // foo()
66   std::unique_ptr<Node> root =
67       std::make_unique<FunctionNode>(std::make_unique<FunctionNameNode>("foo"));
68   SimpleVisitor visitor;
69   root->Accept(&visitor);
70 
71   EXPECT_THAT(visitor.nodes(),
72               ElementsAre(EqualsNodeInfo("foo", NodeType::kFunctionName),
73                           EqualsNodeInfo("", NodeType::kFunction)));
74 
75   std::string_view query = "foo(\"bar\")";
76   std::vector<std::unique_ptr<Node>> args;
77   args.push_back(std::make_unique<StringNode>("bar", query.substr(5, 3)));
78   root = std::make_unique<FunctionNode>(
79       std::make_unique<FunctionNameNode>("foo"), std::move(args));
80   visitor = SimpleVisitor();
81   root->Accept(&visitor);
82 
83   EXPECT_THAT(visitor.nodes(),
84               ElementsAre(EqualsNodeInfo("foo", NodeType::kFunctionName),
85                           EqualsNodeInfo("bar", NodeType::kString),
86                           EqualsNodeInfo("", NodeType::kFunction)));
87 
88   query = "foo(bar(\"baz\"))";
89   std::vector<std::unique_ptr<Node>> inner_args;
90   inner_args.push_back(std::make_unique<StringNode>("baz", query.substr(9, 3)));
91   args.clear();
92   args.push_back(std::make_unique<FunctionNode>(
93       std::make_unique<FunctionNameNode>("bar"), std::move(inner_args)));
94   root = std::make_unique<FunctionNode>(
95       std::make_unique<FunctionNameNode>("foo"), std::move(args));
96   visitor = SimpleVisitor();
97   root->Accept(&visitor);
98 
99   EXPECT_THAT(visitor.nodes(),
100               ElementsAre(EqualsNodeInfo("foo", NodeType::kFunctionName),
101                           EqualsNodeInfo("bar", NodeType::kFunctionName),
102                           EqualsNodeInfo("baz", NodeType::kString),
103                           EqualsNodeInfo("", NodeType::kFunction),
104                           EqualsNodeInfo("", NodeType::kFunction)));
105 }
106 
TEST(AbstractSyntaxTreeTest,Restriction)107 TEST(AbstractSyntaxTreeTest, Restriction) {
108   std::string_view query = "sender.name:(IMPORTANT OR URGENT)";
109   std::vector<std::unique_ptr<TextNode>> member_args;
110   member_args.push_back(
111       std::make_unique<TextNode>("sender", query.substr(0, 6)));
112   member_args.push_back(std::make_unique<TextNode>("name", query.substr(7, 4)));
113 
114   std::vector<std::unique_ptr<Node>> or_args;
115   or_args.push_back(
116       std::make_unique<TextNode>("IMPORTANT", query.substr(13, 9)));
117   or_args.push_back(std::make_unique<TextNode>("URGENT", query.substr(26, 6)));
118 
119   std::vector<std::unique_ptr<Node>> has_args;
120   has_args.push_back(std::make_unique<MemberNode>(std::move(member_args),
121                                                   /*function=*/nullptr));
122   has_args.push_back(
123       std::make_unique<NaryOperatorNode>("OR", std::move(or_args)));
124 
125   std::unique_ptr<Node> root =
126       std::make_unique<NaryOperatorNode>(":", std::move(has_args));
127 
128   SimpleVisitor visitor;
129   root->Accept(&visitor);
130 
131   EXPECT_THAT(visitor.nodes(),
132               ElementsAre(EqualsNodeInfo("sender", NodeType::kText),
133                           EqualsNodeInfo("name", NodeType::kText),
134                           EqualsNodeInfo("", NodeType::kMember),
135                           EqualsNodeInfo("IMPORTANT", NodeType::kText),
136                           EqualsNodeInfo("URGENT", NodeType::kText),
137                           EqualsNodeInfo("OR", NodeType::kNaryOperator),
138                           EqualsNodeInfo(":", NodeType::kNaryOperator)));
139 }
140 
141 }  // namespace
142 }  // namespace lib
143 }  // namespace icing
144