#include #include #include #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 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 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{}), 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()})))), "(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