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