diff options
author | vvvv <[email protected]> | 2024-11-06 10:40:15 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2024-11-06 10:50:39 +0300 |
commit | 8cf98f8169af124576399a29eac2bc2a691124e3 (patch) | |
tree | 54260d85e28822402e0d17d1e840ccfb62b33b61 /yql/essentials/ast/yql_expr_builder_ut.cpp | |
parent | 13cc9ffc62224711fd2923aed53525fc7d1838f8 (diff) |
Moved yql/ast YQL-19206
init
commit_hash:a6a63582073784b9318cc04ffcc1e212f3df703b
Diffstat (limited to 'yql/essentials/ast/yql_expr_builder_ut.cpp')
-rw-r--r-- | yql/essentials/ast/yql_expr_builder_ut.cpp | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/yql/essentials/ast/yql_expr_builder_ut.cpp b/yql/essentials/ast/yql_expr_builder_ut.cpp new file mode 100644 index 00000000000..eb0f2a0bf16 --- /dev/null +++ b/yql/essentials/ast/yql_expr_builder_ut.cpp @@ -0,0 +1,690 @@ +#include "yql_expr.h" +#include <library/cpp/testing/unittest/registar.h> + +namespace NYql { + +Y_UNIT_TEST_SUITE(TExprBuilder) { + Y_UNIT_TEST(TestEmpty) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Build(), yexception); + } + + Y_UNIT_TEST(TestRootAtom) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()).Atom("ABC").Build(); + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Content(), "ABC"); + } + + Y_UNIT_TEST(TestRootAtomTwice) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Atom("ABC") + .Atom("ABC") + .Build(), yexception); + } + + Y_UNIT_TEST(TestRootEmptyList) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()).List().Seal().Build(); + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 0); + } + + Y_UNIT_TEST(TestRootEmptyListTwice) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List() + .List() + .Build(), yexception); + } + + Y_UNIT_TEST(TestListWithAtoms) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .List() + .Atom(0, "ABC") + .Atom(1, "XYZ") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ"); + } + + Y_UNIT_TEST(TestMismatchChildIndex) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List() + .Atom(1, "") + .Build(), yexception); + } + + Y_UNIT_TEST(TestListWithAdd) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .List() + .Add(0, ctx.Builder(TPositionHandle()).Atom("ABC").Build()) + .Atom(1, "XYZ") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ"); + } + + Y_UNIT_TEST(TestNestedListWithAtoms) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .List() + .List(0) + .Atom(0, "ABC") + .Atom(1, "DEF") + .Seal() + .Atom(1, "XYZ") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ"); + } + + Y_UNIT_TEST(TestWrongLevelBuild) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongLevelSeal) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Seal(), yexception); + } + + Y_UNIT_TEST(TestCallableWithAtoms) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Callable("Func") + .Atom(0, "ABC") + .Atom(1, "XYZ") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func"); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ"); + } + + Y_UNIT_TEST(TestNestedCallableWithAtoms) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Callable("Func1") + .Callable(0, "Func2") + .Atom(0, "ABC") + .Atom(1, "DEF") + .Seal() + .Atom(1, "XYZ") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func1"); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "Func2"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ"); + } + + Y_UNIT_TEST(TestRootWorld) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()).World().Build(); + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::World); + } + + Y_UNIT_TEST(TestCallableWithWorld) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Callable("Func") + .World(0) + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func"); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::World); + } + + Y_UNIT_TEST(TestIncompleteRootLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Build(), yexception); + } + + Y_UNIT_TEST(TestIncompleteInnerLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List() + .Lambda() + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestRootLambda) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()).Lambda().Atom("ABC").Seal().Build(); + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC"); + } + + Y_UNIT_TEST(TestRootLambdaWithBodyAsSet) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Set(ctx.Builder(TPositionHandle()).Atom("ABC").Build()) + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC"); + } + + Y_UNIT_TEST(TestInnerLambdaWithParam) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .List() + .Lambda(0) + .Param("x") + .Atom("ABC") + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Content(), "x"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "ABC"); + } + + Y_UNIT_TEST(TestDuplicateLambdaParamNames) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Param("x") + .Atom("ABC") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestParamAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Param("aaa") + .Build(), yexception); + } + + Y_UNIT_TEST(TestParamInList) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List() + .Param("aaa") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestParamInCallable) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Callable("Func") + .Param("aaa") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestParamAfterLambdaBody) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Param("aaa") + .Atom("ABC") + .Param("bbb") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestIndexedAtomAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Atom(0, "ABC") + .Build(), yexception); + } + + Y_UNIT_TEST(TestIndexedListAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .List(0) + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestIndexedWorldAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .World(0) + .Build(), yexception); + } + + Y_UNIT_TEST(TestIndexedCallableAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Callable(0, "Func") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestIndexedLambdaAtRoot) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda(0) + .Atom("ABC") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongIndexAtomAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Atom(1, "ABC") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongIndexListAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .List(1) + .Seal() + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongIndexWorldAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .World(1) + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongIndexCallableAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Callable(1, "Func") + .Seal() + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongIndexLambdaAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Lambda(1) + .Atom("ABC") + .Seal() + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestAddAtLambda) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()) + .Lambda() + .Add(1, ctx.Builder(TPositionHandle()).Atom("ABC").Build()) + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestLambdaWithArgAsBody) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Param("y") + .Arg("x") + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y"); + UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestIndexedArgAsLambdaBody) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda() + .Param("x") + .Arg(1, "x") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestWrongArgName) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda() + .Param("x") + .Arg("y") + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestLambdaWithArgInCallables) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Param("y") + .Callable("+") + .Arg(0, "y") + .Arg(1, "x") + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "+"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 2); + UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(1)); + UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestNestedScopeInLambda) { + TExprContext ctx; + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Param("y") + .Callable("Apply") + .Lambda(0) + .Param("x") + .Callable("+") + .Arg(0, "x") + .Arg(1, "y") + .Seal() + .Seal() + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x"); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "Apply"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Content(), "x"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Type(), TExprNode::Callable); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Content(), "+"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->ChildrenSize(), 2); + // nested x + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(0), + res->Child(1)->Head().Head().Child(0)); + // outer y + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(1), + res->Head().Child(1)); + } + + Y_UNIT_TEST(TestNonIndexedArg) { + TExprContext ctx; + UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda() + .Param("x") + .Callable("f") + .Arg("x") + .Seal() + .Seal() + .Build(), yexception); + } + + Y_UNIT_TEST(TestApplyLambdaArgAsRoot) { + TExprContext ctx; + auto lambda = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Arg("x") + .Seal() + .Build(); + + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("y") + .Apply(lambda).With(0, "y").Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y"); + UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestApplyLambdaArgInContainer) { + TExprContext ctx; + auto lambda = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Arg("x") + .Seal() + .Build(); + + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("y") + .List() + .Apply(0, lambda).With(0, "y").Seal() + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y"); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::List); + UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1); + UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestApplyPartialLambdaArgAsRoot) { + TExprContext ctx; + auto lambda = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Callable("Func1") + .Callable(0, "Func2") + .Atom(0, "ABC") + .Arg(1, "x") + .Seal() + .Seal() + .Seal() + .Build(); + + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("y") + .ApplyPartial(lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y"); + UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestApplyPartialLambdaArgInContainer) { + TExprContext ctx; + auto lambda = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Callable("Func1") + .Callable(0, "Func2") + .Atom(0, "ABC") + .Arg(1, "x") + .Seal() + .Seal() + .Seal() + .Build(); + + auto res = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("y") + .Callable("Func3") + .ApplyPartial(0, lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal() + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y"); + UNIT_ASSERT_EQUAL(res->Child(1)->Head().Child(1), res->Head().Child(0)); + } + + Y_UNIT_TEST(TestApplyOuterArg) { + TExprContext ctx; + auto ast = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("x") + .Callable("Func1") + .Atom(0, "p1") + .Lambda(1) + .Callable("Func2") + .Atom(0, "ABC") + .Arg(1, "x") + .Seal() + .Seal() + .Seal() + .Seal() + .Build(); + + auto res1 = ctx.Builder(TPositionHandle()) + .Lambda() + .Param("y") + .Callable("Func3") + .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1)) + .WithNode(*ast->Head().Child(0), "y").Seal() + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res1->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res1->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res1->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res1->Head().ChildrenSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Type(), TExprNode::Argument); + UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Content(), "y"); + UNIT_ASSERT_EQUAL(res1->Child(1)->Head().Child(1), res1->Head().Child(0)); + + auto atom = ctx.Builder(TPositionHandle()) + .Atom("const") + .Build(); + + auto res2 = ctx.Builder(TPositionHandle()) + .Lambda() + .Callable("Func3") + .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1)) + .WithNode(ast->Head().Head(), TExprNode::TPtr(atom)).Seal() + .Seal() + .Seal() + .Build(); + + UNIT_ASSERT_VALUES_EQUAL(res2->Type(), TExprNode::Lambda); + UNIT_ASSERT_VALUES_EQUAL(res2->ChildrenSize(), 2); + UNIT_ASSERT_VALUES_EQUAL(res2->Head().Type(), TExprNode::Arguments); + UNIT_ASSERT_VALUES_EQUAL(res2->Head().ChildrenSize(), 0); + UNIT_ASSERT_EQUAL(res2->Child(1)->Head().ChildPtr(1), atom); + } +} + +} // namespace NYql |