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 = std::make_unique<FunctionNode>("foo");
67 SimpleVisitor visitor;
68 root->Accept(&visitor);
69
70 EXPECT_THAT(visitor.nodes(),
71 ElementsAre(EqualsNodeInfo("foo", NodeType::kFunction)));
72
73 std::string_view query = "foo(\"bar\")";
74 std::vector<std::unique_ptr<Node>> args;
75 args.push_back(std::make_unique<StringNode>("bar", query.substr(5, 3)));
76 root = std::make_unique<FunctionNode>("foo", std::move(args));
77 visitor = SimpleVisitor();
78 root->Accept(&visitor);
79
80 EXPECT_THAT(visitor.nodes(),
81 ElementsAre(EqualsNodeInfo("bar", NodeType::kString),
82 EqualsNodeInfo("foo", NodeType::kFunction)));
83
84 query = "foo(bar(\"baz\"))";
85 std::vector<std::unique_ptr<Node>> inner_args;
86 inner_args.push_back(std::make_unique<StringNode>("baz", query.substr(9, 3)));
87 args.clear();
88 args.push_back(std::make_unique<FunctionNode>("bar", std::move(inner_args)));
89 root = std::make_unique<FunctionNode>("foo", std::move(args));
90 visitor = SimpleVisitor();
91 root->Accept(&visitor);
92
93 EXPECT_THAT(visitor.nodes(),
94 ElementsAre(EqualsNodeInfo("baz", NodeType::kString),
95 EqualsNodeInfo("bar", NodeType::kFunction),
96 EqualsNodeInfo("foo", NodeType::kFunction)));
97 }
98
TEST(AbstractSyntaxTreeTest,Restriction)99 TEST(AbstractSyntaxTreeTest, Restriction) {
100 std::string_view query = "sender.name:(IMPORTANT OR URGENT)";
101 std::vector<std::unique_ptr<TextNode>> member_args;
102 member_args.push_back(
103 std::make_unique<TextNode>("sender", query.substr(0, 6)));
104 member_args.push_back(std::make_unique<TextNode>("name", query.substr(7, 4)));
105
106 std::vector<std::unique_ptr<Node>> or_args;
107 or_args.push_back(
108 std::make_unique<TextNode>("IMPORTANT", query.substr(13, 9)));
109 or_args.push_back(std::make_unique<TextNode>("URGENT", query.substr(26, 6)));
110
111 std::vector<std::unique_ptr<Node>> has_args;
112 has_args.push_back(std::make_unique<MemberNode>(std::move(member_args),
113 /*function=*/nullptr));
114 has_args.push_back(
115 std::make_unique<NaryOperatorNode>("OR", std::move(or_args)));
116
117 std::unique_ptr<Node> root =
118 std::make_unique<NaryOperatorNode>(":", std::move(has_args));
119
120 SimpleVisitor visitor;
121 root->Accept(&visitor);
122
123 EXPECT_THAT(visitor.nodes(),
124 ElementsAre(EqualsNodeInfo("sender", NodeType::kText),
125 EqualsNodeInfo("name", NodeType::kText),
126 EqualsNodeInfo("", NodeType::kMember),
127 EqualsNodeInfo("IMPORTANT", NodeType::kText),
128 EqualsNodeInfo("URGENT", NodeType::kText),
129 EqualsNodeInfo("OR", NodeType::kNaryOperator),
130 EqualsNodeInfo(":", NodeType::kNaryOperator)));
131 }
132
133 } // namespace
134 } // namespace lib
135 } // namespace icing
136