1f88b2170SEd Tanous #include "filter_expr_parser_ast.hpp"
2f88b2170SEd Tanous #include "filter_expr_printer.hpp"
3f88b2170SEd Tanous 
4f88b2170SEd Tanous #include <optional>
5f88b2170SEd Tanous #include <string_view>
6f88b2170SEd Tanous 
7f88b2170SEd Tanous #include "gmock/gmock.h"
8f88b2170SEd Tanous 
9f88b2170SEd Tanous namespace redfish
10f88b2170SEd Tanous {
11f88b2170SEd Tanous 
parse(std::string_view filterExpression,std::string_view outputAst)12f88b2170SEd Tanous static void parse(std::string_view filterExpression, std::string_view outputAst)
13f88b2170SEd Tanous {
14f88b2170SEd Tanous     std::optional<filter_ast::LogicalAnd> ast = parseFilter(filterExpression);
15f88b2170SEd Tanous     FilterExpressionPrinter pr;
16f88b2170SEd Tanous     EXPECT_TRUE(ast);
17f88b2170SEd Tanous     if (ast)
18f88b2170SEd Tanous     {
19f88b2170SEd Tanous         EXPECT_EQ(pr(*ast), outputAst);
20f88b2170SEd Tanous     }
21f88b2170SEd Tanous }
22f88b2170SEd Tanous 
TEST(FilterParser,SpecificationExamples)23f88b2170SEd Tanous TEST(FilterParser, SpecificationExamples)
24f88b2170SEd Tanous {
25f88b2170SEd Tanous     parse("ProcessorSummary/Count eq 2",
26f88b2170SEd Tanous           "unquoted_string(\"ProcessorSummary/Count\") Equals int(2)");
27f88b2170SEd Tanous     parse(
28f88b2170SEd Tanous         "ProcessorSummary/Count ge 2",
29f88b2170SEd Tanous         "unquoted_string(\"ProcessorSummary/Count\") Greater Than Or Equal int(2)");
30f88b2170SEd Tanous     parse("ProcessorSummary/Count gt 2",
31f88b2170SEd Tanous           "unquoted_string(\"ProcessorSummary/Count\") Greater Than int(2)");
32f88b2170SEd Tanous     parse(
33f88b2170SEd Tanous         "MemorySummary/TotalSystemMemoryGiB le 64",
34f88b2170SEd Tanous         "unquoted_string(\"MemorySummary/TotalSystemMemoryGiB\") Less Than Or Equal int(64)");
35f88b2170SEd Tanous     parse(
36f88b2170SEd Tanous         "MemorySummary/TotalSystemMemoryGiB lt 64",
37f88b2170SEd Tanous         "unquoted_string(\"MemorySummary/TotalSystemMemoryGiB\") Less Than int(64)");
38f88b2170SEd Tanous     parse(
39f88b2170SEd Tanous         "SystemType ne 'Physical'",
40f88b2170SEd Tanous         R"(unquoted_string("SystemType") Not Equal quoted_string("Physical"))");
41f88b2170SEd Tanous     parse(
42f88b2170SEd Tanous         "ProcessorSummary/Count eq 2 or ProcessorSummary/Count eq 4",
43f88b2170SEd Tanous         R"((unquoted_string("ProcessorSummary/Count") Equals int(2)) or (unquoted_string("ProcessorSummary/Count") Equals int(4)))");
44f88b2170SEd Tanous     parse("not ProcessorSummary/Count eq 2",
45f88b2170SEd Tanous           "not(unquoted_string(\"ProcessorSummary/Count\") Equals int(2))");
46f88b2170SEd Tanous     parse("not ProcessorSummary/Count eq -2",
47f88b2170SEd Tanous           "not(unquoted_string(\"ProcessorSummary/Count\") Equals int(-2))");
48f88b2170SEd Tanous     parse("Status/State eq 'Enabled')",
49f88b2170SEd Tanous           R"(unquoted_string("Status/State") Equals quoted_string("Enabled"))");
50f88b2170SEd Tanous     parse(
51f88b2170SEd Tanous         "ProcessorSummary/Count eq 2 and MemorySummary/TotalSystemMemoryGiB eq 64",
52f88b2170SEd Tanous         R"((unquoted_string("ProcessorSummary/Count") Equals int(2)) and (unquoted_string("MemorySummary/TotalSystemMemoryGiB") Equals int(64)))");
53f88b2170SEd Tanous     parse(
54f88b2170SEd Tanous         "Status/State eq 'Enabled' and Status/Health eq 'OK' or SystemType eq 'Physical'",
55f88b2170SEd Tanous         R"((unquoted_string("Status/State") Equals quoted_string("Enabled")) and ((unquoted_string("Status/Health") Equals quoted_string("OK")) or (unquoted_string("SystemType") Equals quoted_string("Physical"))))");
56f88b2170SEd Tanous     parse(
57f88b2170SEd Tanous         "(Status/State eq 'Enabled' and Status/Health eq 'OK') or SystemType eq 'Physical'",
58f88b2170SEd Tanous         R"(((unquoted_string("Status/State") Equals quoted_string("Enabled")) and (unquoted_string("Status/Health") Equals quoted_string("OK"))) or (unquoted_string("SystemType") Equals quoted_string("Physical")))");
59f88b2170SEd Tanous }
60f88b2170SEd Tanous 
TEST(FilterParser,BasicOperations)61f88b2170SEd Tanous TEST(FilterParser, BasicOperations)
62f88b2170SEd Tanous {
63f88b2170SEd Tanous     // Negation
64f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("not(ProcessorSummary/Count eq 2)"));
65f88b2170SEd Tanous 
66f88b2170SEd Tanous     // Negative numbers
67f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("not(ProcessorSummary/Count eq -2)"));
68f88b2170SEd Tanous 
69f88b2170SEd Tanous     // Empty strings
70f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("(foo eq '')"));
71f88b2170SEd Tanous 
72f88b2170SEd Tanous     // Identity
73f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("1 eq 1"));
74f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'foo' eq 'foo'"));
75f88b2170SEd Tanous 
76f88b2170SEd Tanous     // Inverted params
77f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("2 eq ProcessorSummary/Count"));
78f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'OK' eq Status/Health"));
79f88b2170SEd Tanous 
80f88b2170SEd Tanous     // Floating point
81f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("Reading eq 4.0"));
82f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("Reading eq 1e20"));
83f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("Reading eq 1.575E1"));
84f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("Reading eq -2.5E-3"));
85f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("Reading eq 25E-4"));
86f88b2170SEd Tanous 
87f88b2170SEd Tanous     // numeric operators
88f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count eq 2"));
89f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count ne 2"));
90f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count gt 2"));
91f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count ge 2"));
92f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count lt 2"));
93f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count le 2"));
94f88b2170SEd Tanous 
95f88b2170SEd Tanous     // String comparison
96f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count eq 'foo'"));
97f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count ne 'foo'"));
98f88b2170SEd Tanous 
99f88b2170SEd Tanous     // Future, datetime values are strings and need to be compared
100f88b2170SEd Tanous     // Make sure they parse
101f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count lt 'Physical'"));
102f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count le 'Physical'"));
103f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count gt 'Physical'"));
104f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("ProcessorSummary/Count ge 'Physical'"));
105f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'Physical' lt ProcessorSummary/Count"));
106f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'Physical' le ProcessorSummary/Count"));
107f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'Physical' gt ProcessorSummary/Count"));
108f88b2170SEd Tanous     EXPECT_TRUE(parseFilter("'Physical' ge ProcessorSummary/Count"));
109f88b2170SEd Tanous }
110*2261a982SEd Tanous 
TEST(FilterParser,Spaces)111*2261a982SEd Tanous TEST(FilterParser, Spaces)
112*2261a982SEd Tanous {
113*2261a982SEd Tanous     // Strings with spaces
114*2261a982SEd Tanous     parse("foo eq ' '", R"(unquoted_string("foo") Equals quoted_string(" "))");
115*2261a982SEd Tanous 
116*2261a982SEd Tanous     // Lots of spaces between args
117*2261a982SEd Tanous     parse("foo       eq       ''",
118*2261a982SEd Tanous           R"(unquoted_string("foo") Equals quoted_string(""))");
119*2261a982SEd Tanous 
120*2261a982SEd Tanous     // Lots of spaces between parens
121*2261a982SEd Tanous     parse("(      foo eq ''      )",
122*2261a982SEd Tanous           R"(unquoted_string("foo") Equals quoted_string(""))");
123*2261a982SEd Tanous 
124*2261a982SEd Tanous     parse("not           foo eq ''",
125*2261a982SEd Tanous           R"(not(unquoted_string("foo") Equals quoted_string("")))");
126*2261a982SEd Tanous }
127*2261a982SEd Tanous 
TEST(FilterParser,Failures)128f88b2170SEd Tanous TEST(FilterParser, Failures)
129f88b2170SEd Tanous {
130f88b2170SEd Tanous     // Invalid expressions
131f88b2170SEd Tanous     EXPECT_FALSE(parseFilter("("));
132f88b2170SEd Tanous     EXPECT_FALSE(parseFilter(")"));
133f88b2170SEd Tanous     EXPECT_FALSE(parseFilter("()"));
134f88b2170SEd Tanous     EXPECT_FALSE(parseFilter(""));
135f88b2170SEd Tanous     EXPECT_FALSE(parseFilter(" "));
136f88b2170SEd Tanous     EXPECT_FALSE(parseFilter("ProcessorSummary/Count eq"));
137f88b2170SEd Tanous     EXPECT_FALSE(parseFilter("eq ProcessorSummary/Count"));
138f88b2170SEd Tanous     EXPECT_FALSE(parseFilter("not(ProcessorSummary/Count)"));
139f88b2170SEd Tanous }
140f88b2170SEd Tanous } // namespace redfish
141