memgraph/tests/unit/query_pretty_print.cpp

145 lines
5.0 KiB
C++

#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/pretty_print.hpp"
#include "query_common.hpp"
#include "utils/string.hpp"
using namespace query;
using query::test_common::ToString;
using testing::ElementsAre;
using testing::UnorderedElementsAre;
namespace {
struct ExpressionPrettyPrinterTest : public ::testing::Test {
storage::Storage db;
storage::Storage::Accessor storage_dba{db.Access()};
query::DbAccessor dba{&storage_dba};
AstStorage storage;
};
TEST_F(ExpressionPrettyPrinterTest, Literals) {
// 1
EXPECT_EQ(ToString(LITERAL(1)), "1");
// "hello"
EXPECT_EQ(ToString(LITERAL("hello")), "\"hello\"");
// null
EXPECT_EQ(ToString(LITERAL(TypedValue())), "null");
// true
EXPECT_EQ(ToString(LITERAL(true)), "true");
// false
EXPECT_EQ(ToString(LITERAL(false)), "false");
// [1 null "hello"]
std::vector<storage::PropertyValue> values{storage::PropertyValue(1), storage::PropertyValue(),
storage::PropertyValue("hello")};
EXPECT_EQ(ToString(LITERAL(storage::PropertyValue(values))), "[1, null, \"hello\"]");
// {hello: 1, there: 2}
std::map<std::string, storage::PropertyValue> map{{"hello", storage::PropertyValue(1)},
{"there", storage::PropertyValue(2)}};
EXPECT_EQ(ToString(LITERAL(storage::PropertyValue(map))), "{\"hello\": 1, \"there\": 2}");
}
TEST_F(ExpressionPrettyPrinterTest, Identifiers) {
// x
EXPECT_EQ(ToString(IDENT("x")), "(Identifier \"x\")");
// hello_there
EXPECT_EQ(ToString(IDENT("hello_there")), "(Identifier \"hello_there\")");
}
TEST_F(ExpressionPrettyPrinterTest, Reducing) {
// all(x in list where x.prop = 42)
auto prop = dba.NameToProperty("prop");
EXPECT_EQ(ToString(ALL("x", LITERAL(std::vector<storage::PropertyValue>{}),
WHERE(EQ(PROPERTY_LOOKUP("x", prop), LITERAL(42))))),
"(All (Identifier \"x\") [] (== (PropertyLookup "
"(Identifier \"x\") \"prop\") 42))");
// reduce(accumulator = initial_value, variable IN list | expression)
EXPECT_EQ(ToString(REDUCE("accumulator", IDENT("initial_value"), "variable", IDENT("list"), IDENT("expression"))),
"(Reduce (Identifier \"accumulator\") (Identifier \"initial_value\") "
"(Identifier \"variable\") (Identifier \"list\") (Identifier "
"\"expression\"))");
}
TEST_F(ExpressionPrettyPrinterTest, UnaryOperators) {
// not(false)
EXPECT_EQ(ToString(NOT(LITERAL(false))), "(Not false)");
// +1
EXPECT_EQ(ToString(UPLUS(LITERAL(1))), "(+ 1)");
// -1
EXPECT_EQ(ToString(UMINUS(LITERAL(1))), "(- 1)");
// null IS NULL
EXPECT_EQ(ToString(IS_NULL(LITERAL(TypedValue()))), "(IsNull null)");
}
TEST_F(ExpressionPrettyPrinterTest, BinaryOperators) {
// and(null, 5)
EXPECT_EQ(ToString(AND(LITERAL(TypedValue()), LITERAL(5))), "(And null 5)");
// or(5, {hello: "there"}["hello"])
EXPECT_EQ(
ToString(OR(LITERAL(5),
PROPERTY_LOOKUP(MAP(std::make_pair(storage.GetPropertyIx("hello"), LITERAL("there"))), "hello"))),
"(Or 5 (PropertyLookup {\"hello\": \"there\"} \"hello\"))");
// and(coalesce(null, 1), {hello: "there"})
EXPECT_EQ(ToString(AND(COALESCE(LITERAL(TypedValue()), LITERAL(1)),
MAP(std::make_pair(storage.GetPropertyIx("hello"), LITERAL("there"))))),
"(And (Coalesce [null, 1]) {\"hello\": \"there\"})");
}
TEST_F(ExpressionPrettyPrinterTest, Coalesce) {
// coalesce()
EXPECT_EQ(ToString(COALESCE()), "(Coalesce [])");
// coalesce(null, null)
EXPECT_EQ(ToString(COALESCE(LITERAL(TypedValue()), LITERAL(TypedValue()))), "(Coalesce [null, null])");
// coalesce(null, 2, 3)
EXPECT_EQ(ToString(COALESCE(LITERAL(TypedValue()), LITERAL(2), LITERAL(3))), "(Coalesce [null, 2, 3])");
// coalesce(null, 2, assert(false), 3)
EXPECT_EQ(ToString(COALESCE(LITERAL(TypedValue()), LITERAL(2), FN("ASSERT", LITERAL(false)), LITERAL(3))),
"(Coalesce [null, 2, (Function \"ASSERT\" [false]), 3])");
// coalesce(null, assert(false))
EXPECT_EQ(ToString(COALESCE(LITERAL(TypedValue()), FN("ASSERT", LITERAL(false)))),
"(Coalesce [null, (Function \"ASSERT\" [false])])");
// coalesce([null, null])
EXPECT_EQ(ToString(COALESCE(LITERAL(TypedValue(std::vector<TypedValue>{TypedValue(), TypedValue()})))),
"(Coalesce [[null, null]])");
}
TEST_F(ExpressionPrettyPrinterTest, ParameterLookup) {
// and($hello, $there)
EXPECT_EQ(ToString(AND(PARAMETER_LOOKUP(1), PARAMETER_LOOKUP(2))), "(And (ParameterLookup 1) (ParameterLookup 2))");
}
TEST_F(ExpressionPrettyPrinterTest, PropertyLookup) {
// {hello: "there"}["hello"]
EXPECT_EQ(ToString(PROPERTY_LOOKUP(MAP(std::make_pair(storage.GetPropertyIx("hello"), LITERAL("there"))), "hello")),
"(PropertyLookup {\"hello\": \"there\"} \"hello\")");
}
TEST_F(ExpressionPrettyPrinterTest, NamedExpression) {
// n AS 1
EXPECT_EQ(ToString(NEXPR("n", LITERAL(1))), "(NamedExpression \"n\" 1)");
}
} // namespace